前言:
当前看官们对“python37界面”可能比较着重,朋友们都需要剖析一些“python37界面”的相关资讯。那么小编在网络上汇集了一些对于“python37界面””的相关知识,希望同学们能喜欢,咱们快快来了解一下吧!在PySide6图形界面开发模块中,树Tree Widget和表格Table Widget组件的使用方法相对比较复杂,属性的设置和方法的调用都显得很分散、凌乱,短时间内不容易融会贯通。而这两个组件在图形界面开发过程中又要经常用到,尤其是Table Widget表格组件,在进行数据库应用程序开发时又是显示数据的不二选择,因此本篇笔记专门针对这两个难缠的组件进行细致解析。
一、Tree Widget
树形结构是通过根、节点和子节点的包含关系来展现数据的一种常见形式,用于制作图形界面左侧功能栏非常有效,让用户操作更加清晰直观,最典型的应用场景是Windows系统的文件资源管理器。下面对树形结构组件进行介绍:
(一)可视化创建树形结构
1、设置标题栏
在窗口内添加一个Tree Widget组件,然后在这个组件上双击鼠标左键或者按右键选择第一项——Edit Items...,就弹出了Edit Tree Widget设置窗口,窗口内的默认第一个标签页——Columns(列),就是用来设置标题栏的界面。
默认标题栏只有一列,名称是1。在列标题上双击就可以修改列标题文本,利用窗口下方的+和-按钮可以添加和删除列标题(增删列),利用上下箭头↑↓按钮可以调整列的前后顺序,点击右下角Properties<<按钮打开标题属性设置窗口,可以分别对列标题的图标、字体、字号、颜色等属性进行设置。
演示视频如下:
视频加载中...
【注】在属性窗口里设置字体大小和颜色等属性,既繁琐又容易出现bug,所以一般都在主窗口的样式表中使用样式来统一调整这些属性。
2、设置项目
设置项目就是添加树的各个节点和子节点信息。在Tree Widget组件上双击打开编辑窗口,点击Items标签页,点击+按钮添加一个项目并填写文本信息,这样就创建了一个节点。这时,窗口下方的+和-按钮中间又多了一个按钮,点击这个按钮就可以为当前节点添加子节点。同样,上下箭头↑↓按钮旁边也多了两个按钮,用来调节项目的从属关系。点击右下角Properties<<按钮打开项目属性设置窗口,可以对图标和文本格式进行更改。
演示视频如下:
视频加载中...
【注】在演示中可以看到,我们为了让树形结构界面更好看,手动为每个类别添加了图标,但是节点前面自带的三角符号一直都在,影响美观程度。因此,我们在窗口对象的样式表中添加了一段样式语句,用自定义图标替换了Tree Widget组件自带的三角符号。
替换Tree Widget组件自带三角符号图标的样式语句如下:
QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-children:has-siblings{image: url(../icon/r_arrow.png);}QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings{ image: url(../icon/b_arrow.png);}
3、Tree Widget组件的重要属性
contextMenuPolicy:上下文菜单策略,这是所有组件的通用属性QWidget设置中的一项,基本上都是采用默认设置。但是,在Tree Widget组件上想弹出右键菜单,需要将这个属性设置为customContextMenu(定制上下文菜单),否则在Tree Widget组件上右键没有反应editTriggers:编辑触发器,就是什么情况触发信号,内容如下:
NoEditTriggers:没有编辑触发器,即把所有选项都清除选择CurrentChanged:当前项目被改变时触发DoubleClicked:双击触发SelectClicked:选择项目被单击,就是单击触发EditKeyPressed:编辑键被按下时触发,Windows操作系统默认编辑键是F2键,但是默认是给文件和文件夹重命名,貌似在Tree Widge中使用无效AnyKeyPressed:任意键按下时触发AllEditTriggers:所有编辑触发器,即将所有选项都变成选择状态tabkeyNavigation:选项卡导航,是否允许使用Tab键切换项目showDropIndicator:出示放下指示器,当拖放一个项目到另外一个项目上时,在目标项目上显示指示器(目标项目显示一个外框),方便找准位置dragEnabled:是否允许拖拽dragDropOverwriteMode:拖放覆盖写入模式dragDropMode:拖放模式,选项如下:
NoDragDrop:不允许拖放DragOnly:只允许拖拽DropOnly:只允许放下DragDrop:拖放模式,既允许拖拽也允许放下InternalMove:内部移动defaultDropAction:默认放下执行的动作,选项如下:
CopyAction:复制动作MoveAction:移动动作LinkAction:链接动作ActionMask:动作遮罩TargetMoveAction:目标移动动作IgnoreAction:忽视动作alternatingRowColors:交替行颜色,即一行白色一行灰色背景selectionMode:选择模式,选项如下:
NoSelection:不允许选择SingleSelection:单行选择MultiSelection:多行选择ExtendedSelection:扩展选择ContiguousSelection:连续选择selectionBehavior:选择行为,选项如下:
SelectItems:选择项目,即单击时选择一个项目SelectRows:选择行,即单击时选择一行SelectColumns:选择列,即单击时选择一列rootlsDecorated:根装饰,即根节点上用来展开和收缩树结构的标志(三角符号图标),如果设置为真,则显示标志,点击这个标志可以展开和收缩树;如果设置为假,则不显示标志,展开和收缩时需要双击鼠标。这个根装饰图标可以通过样式表,更换成自己的图标uniformRowHeights:统一行高itemsExpandable:项目可扩展sortingEnable:允许排序,设置为真后,标题栏上会出现一个向上或向下的三角符号,点击则来回切换,分别按正序和倒序排列项目animated:生动的,项目展开时的效果allColumnsShowFocus:所有列显示焦点,当该属性为假时,单击一行,只有被点击列有焦点,其它列没有焦点;如果将该属性设置为真,那么点击一行时整行都有焦点headerHidden:标题栏隐藏expandsOnDoubleClick:双击展开columnCount:默认列数headerVisible:标题栏可见headerCascadingSectionResizes:标题栏分类部分重新调整大小的方式,为真时,拖动前一列标题栏调整宽度时,后边相邻标题栏宽度会随之相应改变,即交互调整;为假时,后面相邻标题栏宽度保持固定不变headerDefaultSectionSize:标题栏默认部分尺寸,用来设置节点名称即第一列的宽度headerHighLightSections:高亮显示标题栏分类,即点击某个节点后,标题栏的对应列高亮显示headerMinimumSectionSize:标题栏最小分类尺寸headerShowSortIndicator:标题栏显示排序指示器,三角符号headerStretchLashSection:标题栏最后的分类是否伸展,设置为真,则树的最后一列伸展补充到Tree Widget组件的宽度
(二)使用代码动态构建树形结构
在Qt设计大师里添加Tree Widget组件,不用设置任何属性,剩余工作都在代码里完成。演示代码如下:
from PySide6.QtWidgets import QApplication, QWidget, QTreeWidgetItemfrom PySide6.QtGui import Qt, QFont, QBrush, QColorfrom PySide6.QtCore import QSizefrom ui_test import Ui_Formclass MainWindow(QWidget): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) # 调用树的初始化方法 self.tree_init() # 树的初始化方法 def tree_init(self): self.ui.treeWidget.setColumnCount(2) # 设置树形结构为2列 self.ui.treeWidget.setHeaderLabels(['诗歌名称', '作者']) # 设置标题栏 font = QFont() # 创建字体对象 font.setPointSize(11) # 设置字体对象的文字大小 font.setBold(True) # 设置粗体 self.ui.treeWidget.headerItem().setFont(0, font) # 设置标题栏第一列字体 self.ui.treeWidget.headerItem().setFont(1, font) # 设置标题栏第二列字体 brush = QBrush(QColor(255, 0, 0)) # 创建刷子对象,并将颜色设置为红色 brush_bg = QBrush(QColor(255, 255, 0)) self.ui.treeWidget.headerItem().setForeground(0, brush) # 设置标题栏第一列前景色 self.ui.treeWidget.headerItem().setForeground(1, brush) # 设置标题栏第二列前景色 self.ui.treeWidget.headerItem().setBackground(0, brush_bg) # 设置标题栏第一列背景色 self.ui.treeWidget.headerItem().setBackground(1, brush_bg) # 设置标题栏第二列背景色 self.ui.treeWidget.setColumnWidth(0, 100) # 设置第一列宽度 self.ui.treeWidget.setColumnWidth(1, 80) # 设置第二列宽度 self.ui.treeWidget.headerItem().setTextAlignment(0, Qt.AlignmentFlag.AlignCenter) # 设置第一列对齐方式 self.ui.treeWidget.headerItem().setTextAlignment(1, Qt.AlignmentFlag.AlignCenter) # 设置第二类对齐方式 self.ui.treeWidget.setAlternatingRowColors(True) # 设置隔行颜色显示 # 调用添加树数据方法 self.addTreeData() # 添加树数据方法 def addTreeData(self): # 创建数据字典 data_dict = { '周南': [('关雎', '佚名(先秦)'), ('樛木', '佚名(先秦)'), ('葛覃', '佚名(先秦)'), ('汉广', '佚名(先秦)')], '召南': [('鹊巢', '佚名(先秦)'), ('采蘩', '佚名(先秦)'), ('草虫', '佚名(先秦)')], '邶风': [('柏舟', '佚名(先秦)'), ('绿衣', '佚名(先秦)'), ('日月', '佚名(先秦)')]} for key, value in data_dict.items(): root = QTreeWidgetItem(self.ui.treeWidget) # 创建树形结构的顶级节点项目对象 root.setText(0, key) # 设置顶级节点对象文本 root.setSizeHint(0, QSize(0, 30)) # 设置顶级节点对象行高 self.ui.treeWidget.addTopLevelItem(root) # 在树中添加顶级节点 for item in value: child = QTreeWidgetItem(root) # 创建顶级节点的子节点对象 child.setText(0, item[0]) # 设置第一列文本 child.setText(1, item[1]) # 设置第二列文本 child.setSizeHint(0, QSize(0, 30)) # 设置子节点的行高 child.setTextAlignment(1, Qt.AlignmentFlag.AlignCenter) # 设置子节点的对齐方式 self.ui.treeWidget.addTopLevelItem(child) # 在顶级节点下添加子节点 font = QFont() # 创建字体对象 font.setPointSize(10) # 设置字号为10 self.ui.treeWidget.topLevelWidget().setFont(font) # 设置节点字体if __name__ == '__main__': app = QApplication([]) window = MainWindow() window.show() app.exec()
运行效果如图:
(三)完整实例
本实例界面由两个主要部分组成:左侧是Tree Widget组件,右侧是Text Browser组件。左侧的树形结构用来显示诗经中的分类和具体诗歌,支持弹出菜单,并且在分类和诗歌名称上按右键弹出的菜单是不同的。分类上的弹出菜单用来添加诗歌,诗歌名称上的弹出菜单用来删除诗歌,双击分类则展开包含的所有诗歌,双击诗歌则读取相应的文本文件,并将内容显示在右侧的文本浏览器上。并且,树中的项目支持拖放功能。
1、属性设置及效果演示
视频加载中...
2、实例代码
import osfrom PySide6.QtCore import QSizefrom PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QMenu, QInputDialog, QTreeWidgetItemfrom PySide6.QtGui import QCursor, QAction, Qtfrom ui_tree import Ui_Formclass MainWindow(QWidget): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) # 创建两个菜单对象,一个是添加诗歌菜单,一个是删除诗歌菜单 self.myMenu_add = QMenu(self.ui.treeWidget) self.myMenu_del = QMenu(self.ui.treeWidget) # 创建动作对象 self.action_add = QAction(u'添加诗歌') self.action_del = QAction(u'删除诗歌') # 将相应动作对象添加到相应的菜单里 self.myMenu_add.addAction(self.action_add) self.myMenu_del.addAction(self.action_del) # 添加诗歌菜单项的触发信号和槽 self.action_add.triggered.connect(self.addContent) # 删除诗歌菜单项的触发信号和槽 self.action_del.triggered.connect(self.delContent) # 项目右键菜单信号和槽,将contextMenuPolicy属性要设置为:CustomContextMenu,否则右键无反应 self.ui.treeWidget.customContextMenuRequested.connect(self.pop_menu) # treeWidget组件的双击信号连接到读取文件槽 self.ui.treeWidget.doubleClicked.connect(self.readFile) # 右键弹出菜单 def pop_menu(self): # 判读鼠标右键单击位置项是否有父节点,如果没有父节点,说明是诗歌的类别名称,在鼠标位置显示添加诗歌菜单 item = self.ui.treeWidget.currentItem().parent() if item is None: self.myMenu_add.move(QCursor().pos()) self.myMenu_add.show() else: self.myMenu_del.move(QCursor().pos()) # 如果存在父节点,说明是鼠标右键位置是诗歌名称项,显示删除诗歌菜单 self.myMenu_del.show() # 添加诗歌菜单项对应的方法 def addContent(self): # 利用输入对话框获取多行文本,得到新添加诗歌的内容 result = QInputDialog.getMultiLineText(self, '添加诗歌', '请输入添加诗歌信息(第一行是诗歌名称,第二行是作者名称,以下为诗歌内容):') # 从新添加的诗歌内容字符串开始位置搜索第一个换行符并获取索引,即诗歌名称后面的换行符的位置 index1 = result[0].find('\n') # 从第一个换行符后面开始搜索第二个换行符并获取索引,即作者名称后面的换行符的位置 index2 = result[0].find('\n', index1 + 1) # 在诗歌内容中截取出诗歌名称 name = result[0][:index1] # 在诗歌内容中截取出作者名称 author = result[0][index1 + 1:index2 + 1] if name == '': return # 如果以诗歌名称为文件名的txt文件不存在,则将新添加内容保存到文件 file = name + '.txt' if not os.path.exists(file): with open(file, 'w', encoding='utf-8') as w_file: w_file.write(result[0]) # 获取当前项目,即当前节点 root = self.ui.treeWidget.currentItem() child = QTreeWidgetItem(root) # 创建一个QTreeWidgetItem实例对象 child.setText(0, name.strip()) # 设置新建项目的0列文本为诗歌名称 child.setText(1, author.strip()) # 设置新建项目的1列文本为作者名称 child.setSizeHint(1, QSize(0, 35)) # 设置行高 child.setTextAlignment(0, Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter) # 设置0列水平居左,垂直居中 child.setTextAlignment(1, Qt.AlignmentFlag.AlignCenter) # 设置1列的对齐方式为两个方向都居中 self.ui.treeWidget.addTopLevelItem(child) # 将项目添加到树的节点上 # 删除诗歌菜单项对应的方法 def delContent(self): item=self.ui.treeWidget.currentItem() # 获取当前项目 parent=item.parent() # 获取父节点 parent.removeChild(item) # 移除父节点上的子节点 # 读取文件 def readFile(self): # 获取当前项目的父节点 item = self.ui.treeWidget.currentItem().parent() # 获取当前项目的文本内容 item_name = self.ui.treeWidget.currentItem().text(0) # 当前项目的父节点不是None,则说明该项目是子节点,读取该项目名称对应的文本文件 if item is not None: file = f'{item_name}.txt' if os.path.exists(file): with open(file, 'r', encoding='utf-8') as r_file: content = r_file.read() else: QMessageBox.information(self, '提示', f'《{item_name}》暂时未被收录!') self.ui.textBrowser.setText(content)if __name__ == '__main__': app = QApplication([]) window = MainWindow() window.show() app.exec()二、Table Widget
表格组件,最适合用来展现数据,尤其是配合数据库使用。
(一)可视化创建表格
在Qt设计大师里,创建和设置表格组件的过程和方法与树形结构基本相同,详细情况可以参照上面的Tree Widget的内容,这里只做简单介绍。
1、设置水平标题栏
双击窗体中的Table Widget组件打开编辑窗口,第一个标签页——Columns(编辑列),就是用来设置水平标题的。点击+按钮添加列并设置标题文本信息,所有列标题都设置完毕后点击OK按钮,这样水平标题栏就设置完毕了。水平标题栏的列数决定了表格有多少列,标题栏高度、背景颜色和字体颜色等,统一用样式表来设置。水平标题蓝设置如图所示:
2、设置垂直标题栏
编辑表格组件窗口中的第二个标签页就是用来设置垂直标题的,也就是行标题。如果实际项目中的表格没有行标题,那么就将垂直标题栏设置成数字序列,可以在Table Widget组件属性中隐藏垂直标题栏(水平标题栏也可以隐藏,但是通常都是显示水平标题栏的)。垂直标题栏的行数决定了表格有多少行,行标题的高度随行高的设置而改变。垂直标题栏设置如图所示:
3、设置表格项目
编辑表格组件窗口中的第三个标签页就是用来设置表格项目的,也就是实际的显示内容。表格项目的设置非常简单,首先在表格项里单击或者双击鼠标左键,然后直接录入文本内容就可以了。项目的文字属性统一在Table Widget组件的字体属性中设置,行高也在组件属性中设置,每列的列宽需要单独设置时,需要在代码中完成。
4、Table Widget组件的重要属性
contextMenuPolicy:上下文菜单策略,在代码中需要自定义弹出菜单时,需要将这个属性设置为customContextMenu(定制上下文菜单),否则在Tree Widget组件上右键没有反应editTriggers:编辑触发器,可以设置成不允许编辑表格项目,那么在运行时就不能对表格项目进行更改。也可以设置成单击、双击和编辑键(F2)等方式进入编辑状态,这时可以对表格项目进行更改verticalHeaderDefaultSectionSize:垂直标题栏默认分类尺寸,就是设置行高horizontalHeaderCascadingSectionResizes:水平标题栏分类部分重新调整大小的方式,为真时,拖动前一列标题栏调整宽度时,后边相邻标题栏宽度会随之相应改变,即交互调整;为假时,后面相邻标题栏宽度保持固定不变horizontalHeaderHighLightSections:高亮显示水平标题栏分类,即点击某个项目后,水平标题栏的对应列高亮显示。如果选择行为设置成选择行模式,则点击一行后水平标题栏整体都变成高亮显示,有时会影响表格整体效果,可以关闭这个属性
5、设置样式表
表格的基本属性设置完毕后,如果对表格样式不满意,就需要使用样式表来调整了。使用样式表,还是统一的原则——就是统一在窗口对象的样式表里设置。以下是设置水平标题蓝的样式表,可以根据自己的需要继续扩充内容。样式表内容如下:
QHeaderView::section{color: rgb(182, 0, 0);background-color:rgb(225,225,225);height:30px;}
6、最终效果
(二)使用代码动态构建表格
下面我们完全使用代码,来构建一个表格。这段代码里几乎涵盖了Table Widget组件的所有方法,代码如下:
from PySide6.QtWidgets import QApplication, QMainWindow, QTableWidget, QAbstractItemView, QTableWidgetItemfrom PySide6.QtGui import Qtclass MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() # 创建QTableWidget实例对象 self.myTable = QTableWidget(self) # 调用表格初始化方法 self.table_init() # 表格初始化方法 def table_init(self): self.myTable.move(15, 10) # 设置表格位置 self.myTable.resize(567, 376) # 设置表格尺寸 self.myTable.setColumnCount(7) # 设置表格列数 # 设置每列列宽 self.myTable.setColumnWidth(0, 80) self.myTable.setColumnWidth(1, 60) self.myTable.setColumnWidth(2, 60) self.myTable.setColumnWidth(3, 60) self.myTable.setColumnWidth(4, 80) self.myTable.setColumnWidth(5, 70) self.myTable.setColumnWidth(6, 90) # 设置最后一列充满表宽度 self.myTable.horizontalHeader().setStretchLastSection(True) # 设置水平表头 header = ['姓名', '性别', '年龄', '民族', '籍贯', '学历', '职称'] self.myTable.setHorizontalHeaderLabels(header) # 设置垂直表头不可见 self.myTable.verticalHeader().setVisible(False) # 设置样式表 style = 'QHeaderView::section{color: rgb(182, 0, 0);background-color:rgb(225,225,225);height:30px;}' self.setStyleSheet(style) # 设置隔行区分颜色显示 self.myTable.setAlternatingRowColors(True) # 设置垂直标题栏每行的尺寸,就是行高 self.myTable.verticalHeader().setDefaultSectionSize(30) # 设置水平标题栏调整列宽的方式,为真,拖动调整一列的列宽时,后边相邻的一列的列宽随之相应变化 self.myTable.horizontalHeader().setCascadingSectionResizes(True) # 关闭点击表项对应水平标题栏高亮显示选项 self.myTable.horizontalHeader().setHighlightSections(False) # 设置选择方式,扩展选择 self.myTable.setSelectionMode(QAbstractItemView.ExtendedSelection) # 设置选择行为,选择行 self.myTable.setSelectionBehavior(QAbstractItemView.SelectRows) # 设置编辑触发器,双击或按编辑键时编辑表项 self.myTable.setEditTriggers( QAbstractItemView.EditTrigger.DoubleClicked | QAbstractItemView.EditTrigger.EditKeyPressed) # 设置表格项不可以拖放 self.myTable.setDragDropMode(QAbstractItemView.NoDragDrop) # 调用添加表格项数据方法 self.add_data() # 添加表格项数据方法 def add_data(self): # 要显示的数据 data = [('张三', '男', '32', '汉', '山东', '大专', '助理工程师'), ('李四', '男', '35', '汉', '吉林', '本科', '工程师'), ('王五', '男', '42', '汉', '河北', '大专', '助理工程师'), ('赵六', '男', '38', '汉', '辽宁', '本科', '助理工程师'), ('钱七', '男', '32', '汉', '山西', '本科', '助理工程师'), ('马八', '男', '30', '汉', '山东', '大专', '工程师'), ('周九', '男', '37', '汉', '山东', '大专', '助理工程师'), ('李六', '男', '45', '汉', '河北', '大专', '工程师'), ('张九', '男', '29', '汉', '山东', '本科', '助理工程师')] # 设置表格行数为11 self.myTable.setRowCount(11) # 循环添加数据 for i in range(len(data)): for j in range(len(data[i])): # 在坐标位置添加QTableWidgetItem类数据 self.myTable.setItem(i, j, QTableWidgetItem(data[i][j])) # 设置单元格对齐方式,需要使用Qt类的AlignmentFlag属性 self.myTable.item(i,j).setTextAlignment(Qt.AlignmentFlag.AlignCenter)if __name__ == '__main__': # 创建Qt应用对象,加一个空列表参数 app = QApplication([]) # 创建主窗口对象 window = MainWindow() # 修改窗口尺寸为600*400像素 window.resize(600, 400) # 窗口左上角移动到屏幕上横向500像素纵向210像素处 window.move(500, 210) # 设置窗口标题 window.setWindowTitle('使用代码动态创建表格') # 显示窗口 window.show() # 循环显示,直到点击窗口关闭按钮 app.exec()
运行效果如下:
标签: #python37界面