继续之前的控件按钮(bf_button)、文本框(bf_label)和编辑框(bf_edit)之后,继续增加新控件(bf_table),由于表格的功能比较复杂,可能要分几次编写
大致实现步骤
一:基本展示
二:支持横、列两个方向上的滚动条
三:支持列宽度的自动调整和手动调整
用pygame做的表格控件
主要有以下几个文件
syht.otf 字体文件
bf_common.py 控件父类
bf_panel.py 面板类用于控件管理
bf_table.py 表格控件
example_table.py 测试表格功能
以下是各python文件
bf_common.py
# -*- coding=utf-8 -*-
import threading
import pygame
from pygame.locals import MOUSEBUTTONDOWN
class BFControlId(object):
_instance_lock = threading.Lock()
def __init__(self):
self.id = 1
self.click_id = -1
@classmethod
def instance(cls, *args, **kwargs):
if not hasattr(BFControlId, "_instance"):
BFControlId._instance = BFControlId(*args, **kwargs)
return BFControlId._instance
def get_new_id(self):
self.id += 1
return self.id
class BFBase(object):
def __init__(self):
self.panel = None
self._visible = True
self._text_align = TEXT_ALIGN_MIDDLE
self._font = DEFAULT_SM_FONT
self.ctl_id = BFControlId().instance().get_new_id()
def init_font(self):
pass
def clear_foucs(self):
pass
def clear_hover(self):
pass
@property
def visible(self):
return self._visible
@visible.setter
def visible(self, value):
self._visible = value
@property
def text_align(self):
return self._text_align
@text_align.setter
def text_align(self, value):
self._text_align = value
self.init_font()
@property
def font(self):
return self._font
@font.setter
def font(self, value):
self._font = value
self.init_font()
CLICK_EFFECT_TIME = 100
DEFAULT_FONT = pygame.font.Font(u'syht.otf', 28)
DEFAULT_SM_FONT = pygame.font.Font(u'syht.otf', 20)
def get_default_font(size):
return pygame.font.Font(u'syht.otf', int(size))
TEXT_ALIGN_LEFT = 1
TEXT_ALIGN_MIDDLE = 2
TEXT_ALIGN_RIGHT = 3
bf_panel.py
# -*- coding=utf-8 -*-
import threading
import pygame
class BFPanel(object):
def __init__(self):
self.ctl_list = []
def add_control(self, ctl):
ctl.panel = self
self.ctl_list.append(ctl)
def clear_foucs(self):
for ctl in self.ctl_list: ctl.clear_foucs()
def clear_hover(self):
for ctl in self.ctl_list: ctl.clear_hover()
def update(self, event):
for i in range(len(self.ctl_list)-1, -1, -1):
ctl = self.ctl_list[i]
if not ctl.visible: continue
flag = ctl.update(event)
if flag:
break
# for ctl in self.ctl_list: ctl.update(event)
def draw(self):
for ctl in self.ctl_list: ctl.draw()
bf_table.py
# -*- coding=utf-8 -*-
import time,sys,threading,platform
import pygame
from pygame.locals import MOUSEBUTTONDOWN,KEYDOWN,SCRAP_TEXT
from bf_common import BFControlId,BFBase,DEFAULT_FONT,get_default_font
black = (50,50,50)
class ColInfo(object):
def __init__(self, surface, name, font_image=None, x=0, y=0):
self.surface = surface
self.x = x
self.y = y
self.name = name
self.font_image = font_image
def draw(self):
if self.surface: self.surface.blit(self.font_image, (self.x, self.y))
class RowItem(object):
def __init__(self, surface, val, font_image=None, x=0, y=0):
self.surface = surface
self.x = x
self.y = y
self.val = val
self.font_image = font_image
def draw(self):
if self.surface: self.surface.blit(self.font_image, (self.x, self.y))
class RowInfo(object):
def __init__(self):
self.row_items = []
self.highlight = False
self.surface = None
def draw(self):
if self.highlight and self.surface:
self.surface.fill((218,245,255))
for row_item in self.row_items:
row_item.draw()
CLICK_EFFECT_TIME = 100
class BFTable(BFBase):
def __init__(self, parent, rect, columns, rows):
super(BFTable, self).__init__()
self.x,self.y,self.width,self.height = rect
self.bg_color = (255,255,255)
self.parent = parent
self.surface = parent.subsurface(rect)
self.in_click = False
self.click_loss_time = 0
self.click_event_id = -1
self.ctl_id = BFControlId().instance().get_new_id()
self.header_list = []
self._header_height = 30
self._col_width = self.width / len(columns)
self._row_height = (self.height - self._header_height) / len(rows)
self._min_row_height = 20
self._max_row_height = 30
if self._row_height > self._max_row_height: self._row_height = self._max_row_height
if self._row_height < self._min_row_height: self._row_height = self._min_row_height
self._col_font = get_default_font(self._header_height * 0.5)
self._row_font = get_default_font(self._row_height * 0.6)
self._columns = []
for i in range(len(columns)):
col = columns[i]
col_info = ColInfo(self.surface.subsurface((self._col_width*i,0,self._col_width,self._header_height)), col)
header_image=self._col_font.render(col, True, black)
w, h = header_image.get_size()
col_info.x = (self._col_width - w) / 2
col_info.y = (self._header_height - h) / 2
col_info.font_image = header_image
self._columns.append(col_info)
self._rows = []
for i in range(len(rows)):
y = self._header_height + self._row_height * i
row = rows[i]
row_info = RowInfo()
row_info.surface = None if y + self._row_height > self.height else self.surface.subsurface((0,y,self.width,self._row_height))
if i % 2 == 1: row_info.highlight = True
for j in range(len(row)):
v = row[j]
tmp_rect = (self._col_width*j,y,self._col_width,self._row_height)
tmp_surface = None if y + self._row_height > self.height else self.surface.subsurface(tmp_rect)
item = RowItem(tmp_surface,v)
if sys.version_info >= (3,0) or type(v) is not unicode: v = str(v)
row_image = self._row_font.render(v,True,black)
w, h = row_image.get_size()
item.x = (self._col_width - w) / 2
item.y = (self._row_height - h) / 2
item.font_image = row_image
row_info.row_items.append(item)
self._rows.append(row_info)
def clear_foucs(self):
self.in_edit = False
def update(self, event):
return False
def draw(self):
if not self._visible:
return
grid_color = (100,100,100)
self.surface.subsurface((0,0,self.width,self._header_height)).fill((200,200,200))
pygame.draw.rect(self.surface, grid_color, (0,0,self.width,self._header_height+self._row_height*len(self._rows)),1)
pygame.draw.line(self.surface,grid_color,[0,self._header_height],[self.width,self._header_height], 1)
for col_info in self._columns:
col_info.draw()
for row_info in self._rows:
row_info.draw()
for i in range(1, len(self._rows)):
y = self._header_height + i * self._row_height
pygame.draw.line(self.surface,grid_color,[0,y],[self.width,y], 1)
for i in range(1, len(self._columns)):
x = self._col_width * i
pygame.draw.line(self.surface,grid_color,[x,0],[x,self._header_height+self._row_height * len(self._rows)], 1)
pygame.draw.rect(self.surface, (200,200,200), (0,0,self.width,self.height),1)
example_table.py
# -*- coding=utf-8 -*-
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((600,420))
pygame.scrap.init()
from bf_panel import BFPanel
from bf_table import BFTable
screencaption = pygame.display.set_caption('bf control')
btn_panel = BFPanel()
headers = (u'编号',u'姓名',u'年龄',u'语文成绩',u'数学成绩',u'英语成绩')
rows = []
rows.append((1,u'王小明',11,99,95,91))
rows.append((2,u'李小红',10,97,88,90))
rows.append((3,u'张小强',11,99,100,100))
rows.append((4,u'王小明',11,99,95,91))
rows.append((5,u'李小红',10,97,88,90))
rows.append((6,u'张小强',11,99,100,100))
rows.append((7,u'王小明',11,99,95,91))
rows.append((8,u'李小红',10,97,88,90))
rows.append((9,u'张小强',11,99,100,100))
rows.append((10,u'王小明',11,99,95,91))
rows.append((11,u'李小红',10,97,88,90))
rows.append((12,u'张小强',11,99,100,100))
table = BFTable(screen, (20,20,560,300), headers, rows)
btn_panel.add_control(table)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
btn_panel.update(event)
screen.fill((255,255,255))
btn_panel.draw()
pygame.display.update()
文章浏览阅读1w次,点赞3次,收藏41次。安卓实现工业级静默活体检测,判别机器前出现的人脸是真实还是伪造。用于判别虚假人脸。_安卓 人脸检测
文章浏览阅读3.5k次,点赞4次,收藏20次。Java isDigit() 方法JAVA Character类1.用于判断指定字符是否是数字,返回boolean类型public static boolean isDigit(char ch)2.参数:字符3.测试:public class isDigit { /** * @param args */ public static void main(String[]..._java isdigit
文章浏览阅读79次。2019独角兽企业重金招聘Python工程师标准>>> ..._grep命令配合特殊符号进行各种查询。如:查找 /etc 底下只要含有 xyz 三个字符的任
文章浏览阅读893次。import java.io.InputStream;import java.util.*;import org.apache.jena.rdf.model.Model;import org.apache.jena.rdf.model.ModelFactory;import org.apache.jena.rdf.model.RDFNode;import org.apa..._java 对 ttl文件进行解析
文章浏览阅读3.3k次,点赞5次,收藏43次。文章目录1. 为什么要学习DSSM双塔模型2. DSSM模型理论知识2.1 DSSM模型的原理2.2 DSSM深度语义匹配模型整体结构2.2.1 输入层2.2.2 表示层2.2.3 匹配层2.3 DSSM模型的优缺点3. 推荐领域中的DSSM双塔模型3.1 从NLP领域跨界到推荐领域的DSSM3.2 朴素的DSSM双塔模型,20153.3 百度的双塔模型3.4 谷歌的双塔模型,20194. 实战广告推荐的双塔模型4.1 广告推荐业务场景4.2 广告推荐的DSSM双塔模型结构4.2.1 输入层4.2.2 表示_双塔模型中的sigmoid
文章浏览阅读204次。JavaWeb学习——Servlet学习(Cookie、Session)1.Cookie和Session简单理解问题引出:我想大家都有这种经历,当我们在网页上访问一个网页时,比如博客,邮箱等一些需要登陆的网站。每当我们关闭浏览器,下次再进入该网站时我们还需要再登陆(当然有些浏览器可能会做处理,询问用户是否保存用户名和密码,这个是属于浏览器帮我们做的,不做考虑)。但是当我们登陆上去但是不关闭浏览..._用cookie和session是用sevlet还是java
文章浏览阅读1.3w次,点赞39次,收藏303次。这里写自定义目录标题0. Cache工作原理1. 直接映射优缺点计算方法2. 全相联映射优缺点3. 组相联映射例题1.2.3.0. Cache工作原理1. 直接映射下面针对该映射方式,举一个小例子:当缓存接收到CPU发送来的主存地址后,只需根据中间c位字段(假设为00…01)找到缓存块1,然后根据字块1的”标记”是否与主存地址的高t位相符合,若符合且有效位为1(这里的有效位用来识别Cache存储块中的额数据是否有效,因为有时Cache中的数据是无效的,例如,在初始时刻Cache中的额内容为空,是_四路组相联映射
文章浏览阅读1.8k次,点赞2次,收藏15次。MATLAB一、基本介绍二级目录三级目录二、矩阵运算三、编程基础(1)四、编程基础(2)五、常见函数六、二维图形绘制七、三维图形绘制八、运算符九、流程控制语句十、其他常用函数十一、自定义函数十二、画图进阶一、基本介绍二级目录三级目录二、矩阵运算三、编程基础(1)四、编程基础(2)五、常见函数六、二维图形绘制七、三维图形绘制八、运算符九、流程控制语句十、其他常用函数十一、自定义函数十二、画图进阶..._matlab的setvar
文章浏览阅读2.9k次,点赞3次,收藏7次。VS2022 无法启动程序 不是有效的win32程序_vs不是有效的win32应用程序怎么解决
文章浏览阅读4k次,点赞11次,收藏30次。Unix 是什么电话发明人贝尔于 1877 年创建的美国贝尔电话公司,后来创建了一家子公司叫美国电信业公司,1900年美国电信业公司接管了贝尔公司的全部资产,成为母公司,改名为美国电话电报公司(AT&T),美国电话电报公司有个部门叫贝尔实验室,以肯•汤普森为首的贝尔实验室研究人员于 1969 年实现了一种分时操作系统的雏形,1970 年该系统正式取名为 UNIX。而肯•汤普森的同事丹尼斯•里奇发明了传说中的 C 语言,这是一种适合编写系统软件的高级语言,后来 UNIX 系统的绝大部分源代码都用 C_linux bsd简单描述
文章浏览阅读1.3w次,点赞2次,收藏27次。1. 节点的Name与Title区别。name是根据IDname的命名规则,只能用字母开头,随后跟数组、下划线。不能出现空格或者发音。Title突破了这一限制。系统首选Title,如果没有,用name作为节点名字。2. 节点的Status Value与 Table Value的区别。Status对应着状态的名字,可以是单词,Status Value表示状态对应的值。例如爆炸控制系统中“off”状态_netica 逆向推理
文章浏览阅读799次,点赞18次,收藏18次。本文提出了一种基于麻雀算法优化空间注意力机制卷积神经网络结合门控循环单元SSA-CNN-GRU-SAM-Attention的回归预测模型,用于解决数据多维输入单输出预测问题。该模型将麻雀算法与空间注意力机制卷积神经网络相结合,并加入门控循环单元GRU,以提高模型的预测精度和泛化能力。同时,该模型还采用了SAM注意力机制,进一步增强了模型对重要特征的提取能力。实验结果表明,该模型在多个数据集上取得了良好的预测性能,优于传统回归预测模型。