Pyqt5——表格中隐藏的控件(Model/View/Delegate)
需求:在TableView表格中点击单元格可以实现编辑功能。性别由LineEdite控件编辑,年龄由spinBox控件编辑。
实现:(1)使用Qt的model-view模式生成表格视图。
(2)重写QAbstractItemDelegate类和类中的paint、createEditor、setEditorData、setModelData函数。
(3)重写QAbstractTableModel类。
功能展示:
主要代码:
(1)Model部分。此部分完成数据推送和数据编辑功能。
- class MyTableModel(QAbstractTableModel):
- """Model"""
- def __init__(self):
- super(MyTableModel, self).__init__()
- self._data = []
- self._background_color = []
- self._headers = ['学号', '姓名', '性别', '年龄']
- self._generate_data()
- def _generate_data(self):
- """填充表格数据"""
- name_list = ['张三', '李四', '王五', '王小二', '李美丽', '王二狗']
- for id_num, name in enumerate(name_list):
- self._data.append([str(id_num), name, '男', str(random.randint(20, 25))])
- # :默认单元格颜色为白色
- self._background_color.append([QColor(255, 255, 255) for i in range(4)])
- def rowCount(self, parent=QModelIndex()):
- """返回行数量。"""
- return len(self._data)
- def columnCount(self, parent=QModelIndex()):
- """返回列数量。"""
- return len(self._headers)
- def headerData(self, section, orientation, role):
- """设置表格头"""
- if role == Qt.DisplayRole and orientation == Qt.Horizontal:
- return self._headers[section]
- def data(self, index, role):
- """显示表格中的数据。"""
- if not index.isValid() or not 0 <= index.row() < self.rowCount():
- return QVariant()
- row = index.row()
- col = index.column()
- if role == Qt.DisplayRole:
- return self._data[row][col]
- elif role == Qt.BackgroundColorRole:
- return self._background_color[row][col]
- elif role == Qt.TextAlignmentRole:
- return Qt.AlignCenter
- return QVariant()
- def setData(self, index, value, role):
- """编辑单元格中的数据"""
- if not index.isValid() or not 0 <= index.row() < self.rowCount():
- return QVariant()
- if role == Qt.EditRole:
- if index.column() == 2:
- self._data[index.row()][index.column()] = value
- self.layoutChanged.emit() # 更新数据后要通知表格刷新数据
- return True
- elif index.column() == 3:
- self._data[index.row()][index.column()] = str(value)
- self.layoutChanged.emit()
- return True
- else:
- return False
- def flags(self, index):
- """设置单元格的属性。"""
- if index.column() == 0 or index.column() == 1:
- # :我们设置第0、1列不可编辑,其他列可以编辑。
- return super().flags(index)
- return Qt.ItemIsEditable | super().flags(index)
(2)Delegate部分。此部分完成View中数据的展示,以及单元格中编辑器的生成、编辑器内容的推送和编辑器内容更新到Model。
- class MyDelegate(QAbstractItemDelegate):
- """Delegate"""
- def __init__(self):
- super(MyDelegate, self).__init__()
- def paint(self, painter, option, index):
- """绘制单元格。"""
- if index.column() == 0:
- # :表格第一列是ID,单元格中绘制一个图片和ID。
- p = QStyleOptionViewItem()
- p.index = index
- p.rect = option.rect
- p.features = QStyleOptionViewItem.HasDecoration | QStyleOptionViewItem.HasDisplay
- p.text = str(index.data())
- p.decorationSize = QSize(44, 44) # 设置装饰图标的大小。
- p.icon = QIcon('../image/id.png') # 设置装饰图标路径名
- p.state = option.state
- p.showDecorationSelected = True # 开启选中时,单元格高亮显示
- # :若项目被选择,则高亮绘制其矩形
- p.decorationPosition = QStyleOptionViewItem.Left # 图片在文字的左边
- p.displayAlignment = Qt.AlignLeft | Qt.AlignCenter # 设置文字的位置
- QApplication.style().drawControl(QStyle.CE_ItemViewItem, p, painter)
- else:
- # :向表格中渲染数据,如果缺少下面代码,表格中数据不能正常显示。
- # :这里应该在model的data函数之后调用,此时通过index可以获取要显示。
- # :的数据。
- p = QStyleOptionViewItem()
- p.features = QStyleOptionViewItem.HasDisplay
- p.index = index # 表格QModelIndex索引
- p.rect = option.rect
- p.state = option.state
- p.showDecorationSelected = True # 开启选中时,单元格高亮显示
- p.text = str(index.data()) # 表格中的数据
- QApplication.style().drawControl(QStyle.CE_ItemViewItem, p, painter)
- def createEditor(self, parent, option, index):
- """给单元格创建编辑器(点击单元格的时候调用)"""
- if index.column() == 2:
- # :第2列性别设置为lineEdite编辑器。
- # :注意,在创建编辑控件的时候传入parent防止在编辑时新弹出窗口来进行编辑。
- p = QLineEdit(parent)
- p.setFocusPolicy(Qt.TabFocus)
- # :设置控件的位置,如果忽略此句,控件会出现在窗体的左上角。
- p.setGeometry(option.rect)
- return p
- elif index.column() == 3:
- # :第3列年龄设置为spinBox编辑器。
- p = QSpinBox(parent)
- p.setMaximum(150) # 年龄最大值为150
- p.setGeometry(option.rect)
- return p
- else:
- return super().createEditor(parent, option, index)
- def setEditorData(self, editor, index):
- """把model中的数据填充到编辑器当中(点击单元格的时候调用但晚于createEditor)"""
- if index.column() == 2:
- # :lineEdit编辑器。
- editor.setText(index.data())
- elif index.column() == 3:
- editor.setValue(int(index.data()))
- else:
- super().setEditorData(editor, index)
- def setModelData(self, editor, model, index):
- """把编辑器中的数据更新到model当中(编辑完成时调用)"""
- if index.column() == 2:
- model.setData(index, editor.text(), role=Qt.EditRole)
- elif index.column() == 3:
- model.setData(index, editor.value(), role=Qt.EditRole)
- else:
- super().setModelData(editor, model, index)
Demo源码:
Demo源码参考网址(码云):https://gitee.com/cui_zhen/pyqt5-example
Pyqt5——表格中隐藏的控件(Model/View/Delegate)的更多相关文章
- 在VisualStudio 工具箱中隐藏用户控件
当我们创建一个用户控件后,VisualStudio会自动将其添加到工具箱中,本来这是一个比较贴心的设计.但是,有的时候,我们并不想将用户控件放到工具箱中. 例如:在WPF中,为了避免一个页面的控件过多 ...
- 重写UITableViewCell子类中属性的setter方法来实现隐藏或显示该cell中的某些控件
重写UITableViewCell子类中属性的setter方法来实现隐藏或显示该cell中的某些控件 为什么会需要这样子的一种方法来实现隐藏或者显示一个cell中的某些控件呢? 其实,隐藏cell中某 ...
- (转)客户端触发Asp.net中服务端控件事件
第一章. Asp.net中服务端控件事件是如何触发的 Asp.net 中在客户端触发服务端事件分为两种情况: 一. WebControls中的Button 和HtmlControls中的Type为su ...
- 转:ExpressBars中的停靠控件使用
http://www.cnblogs.com/jxsoft/archive/2011/08/25/2152872.html 1 新手上路 1.1 控件简介 Dock pan ...
- ASP.NET中 WebForm 窗体控件使用及总结【转】
原文链接:http://www.cnblogs.com/ylbtech/archive/2013/03/06/2944675.html ASP.NET中 WebForm 窗体控件使用及总结. 1.A, ...
- HTML5 Web app开发工具Kendo UI Web中Grid网格控件的使用
Kendo UI Web中的Grid控件不仅可以显示数据,并对数据提供了丰富的支持,包括分页.排序.分组.选择等,同时还有着大量的配置选项.使用Kendo DataSource组件,可以绑定到本地的J ...
- android中的EditView控件
android中的EditView控件 EditText继承关系:View-->TextView-->EditText ,EditText是可编辑文本框 1.EditText默认情况下,光 ...
- android中的TextView控件
我以前是搞ssh开发的,现在在搞android开发,所以简单学习了一下,对于自己所了解的做一个记录,也算是一个笔记吧,如果有什么不对的,希望大家给予一定的指导. 一.TextView的基本使用 Te ...
- TWaver初学实战——如何在TWaver属性表中添加日历控件?
在日期输入框中添加日历控件,是一种非常流行和实用的做法.临渊羡鱼不如退而写代码,今天就看看在TWaver中是如何实现的. 资源准备 TWaver的在线使用文档中,就有TWaver Proper ...
随机推荐
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) E. Let Them Slide(数据结构+差分)
题意:问你有n个长度总和为n的数组 你可以移动数组 但不能移出长度为w的矩形框 问你每一列的最大值是多少? 思路:只有一次询问 我们可以考虑差分来解决 然后对于每一行数组 我们可以用数据结构维护一下 ...
- 【洛谷 p3383】模板-线性筛素数(数论)
题目:给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内).(N<=10000000,M<=100000) 解法:1.欧拉筛O(n),数组近乎100KB:2.( ...
- 【洛谷 p3379】模板-最近公共祖先(图论--倍增算法求LCA)
题目:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 解法:倍增. 1 #include<cstdio> 2 #include<cstdlib> 3 #include ...
- Codeforces Round #649 (Div. 2) C. Ehab and Prefix MEXs
题目链接:https://codeforces.com/contest/1364/problem/C 题意 给出大小为 $n$ 的非递减数组 $a$,构造同样大小的数组 $b$,使得对于每个 $i$, ...
- 【noi 2.5_7834】分成互质组(dfs)
有2种dfs的方法: 1.存下每个组的各个数和其质因数,每次对于新的一个数,与各组比对是否互质,再添加或不添加入该组. 2.不存质因数了,直接用gcd,更加快.P.S.然而我不知道为什么RE,若有好心 ...
- hdu5437 Alisha’s Party
Problem Description Princess Alisha invites her friends to come to her birthday party. Each of her f ...
- CF1400-D. Zigzags
CF1400-D. Zigzags 题意: 给出一个由\(n\)个数字构成的数组\(a\),让你在这个数组中找出有多少个符合以下要求的元组\((i,j,k,l)\): 1. \(i<j<k ...
- K8S(05)核心插件-ingress(服务暴露)控制器-traefik
K8S核心插件-ingress(服务暴露)控制器-traefik 1 K8S两种服务暴露方法 前面通过coredns在k8s集群内部做了serviceNAME和serviceIP之间的自动映射,使得不 ...
- 二进制安装kubernetes(七) 部署知识点总结
1.k8s各个组件之间通信,在高版本中,基本都是使用TSL通信,所以申请证书,是必不可少的,而且建议使用二进制安装,或者在接手一套K8S集群的时候,第一件事情是检查证书有效期,证书过期或者TSL通信问 ...
- 2.使用Helm构建ElasticSearch集群
作者 微信:tangy8080 电子邮箱:914661180@qq.com 更新时间:2019-05-24 16:08:53 星期五 欢迎您订阅和分享我的订阅号,订阅号内会不定期分享一些我自己学习过程 ...