一、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}》暂时未被收录!
二、Table Widget
') self.ui.textBrowser.setText(content)if __name__ == '__main__': app = QApplication([]) window = MainWindow() window.show() app.exec()
表格组件,最适宜用来展现数据,尤其是合营数据库利用。
(一)可视化创建表格
在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() # 修正窗口尺寸为600400像素 window.resize(600, 400) # 窗口左上角移动到屏幕上横向500像素纵向210像素处 window.move(500, 210) # 设置窗口标题 window.setWindowTitle('利用代码动态创建表格') # 显示窗口 window.show() # 循环显示,直到点击窗口关闭按钮 app.exec()
运行效果如下: