pyqt5 tableWidget入门,和treewidget联动功能

2023-11-08

1.成品

最近在做项目的过程中需要用到QTreeWidget和QTableWidget联动,上一篇文章介绍了 QTreeWidget的基本用法,这里介绍一下QTableWidget的基本用法,及我在项目中的使用。先看看最终成品。

在这里插入图片描述要实现以上图片中的功能,需要在上一篇文中加上QTableWidget。所以先介绍下QTableWidget。

2. QTableWidget类

QTableWidget类中的常用方法如下表:

方 法 描 述
setRowCount(int row) 设置QTableWidget表格控件行数
setColumnCount(int col) 设置QTableWidget表格控件列数
setHorizontalHeaderLabels() 设置QTableWidget表格控件的水平标签
setVeriticalHeaderLabels() 设置QTableWidget表格控件的垂直标签
setItem(int, int, QTableWidgetItem) 在QTableWidget表格控件的每个选项的单元空间里添加控件
horizontalHeader 获取QTableWidget表格控件的表格头,以便执行隐藏
rowCount() 获取QTableWidget表格控件的行数
columnCount() 获取QTableWidget表格控件的列数
setEditTriggers(EditTriggers triggers) 设置表格是否可编辑。设置编辑规则的枚举值
setSelectionBehavior 设置表格的选择行为
setTextAlignment 设置表格内文字的对齐方式
setSpan(int row, int column, int rowSpanCount, int columnSpanCount) 合并单元格,要改变单元格的第row行第column列,要合并rowSpanCount行数和columnSpanCount列数。
·row: 要改变的单元格行数
·column要改变的单元格列数
·rowSpanCount:需要合并的行数
·columnSpanCount:需要合并的列数
setShowGrid() 在默认情况下,表格的显示是有网格线的。
· True:显示网格线
· False:不显示网格线
setColumnWidth(int column, int width) 设置单元格的宽度
setRowHeight(int row, int height) 设置单元格的高度

编辑规则中的枚举类型:

选 项 描述
QAbstractItemView:NoEditTriggers0No 0 不能对表格内容进行修改
QAbstractItemView:CurrentChanged1Editing 1 任何时候都能对单元格进行修改
QAbstractItemView:DoubleClicked2Editing 2 双击单元格
QAbstractItemView:SelectedClicked4Editing 4 单击已选中的内容
QAbstractItemView:EditKeyPressed8Editing 8 当修改键被按下时修改单元格
QAbstractItemView:AnyKeyPressed16Editing 16 按任意键修改单元格
QAbstractItemView:AllEditTriggers31Editing 31 包括以上所有条件

表格的选择行为的枚举值类型:

选 项 描述
QAbstractItemView.SelectItems0Selecting 0 选中单个单元格
QAbstractItemView.SelectRows1Selecting 1 选中一行
QAbstractItemView.SelectColumns2Selecting 2 选中一列

单元格文本的水平对齐方式:

选 项 描 述
Qt.AlignLeft 将单元格的内容沿单元格的左边缘对齐
Qt.AlignRight 将单元格的内容沿单元格的右边缘对齐
Qt.AlignHCenter 在可用空间中,居中显示在水平向上
Qt.AlignJustify 将文本在可用空间中对齐,默认是从左到右

单元格文本的垂直对齐方式:

选 项 描 述
Qt.AlignTop 与顶部对齐
Qt.AlignBottom 与底部对齐
Qt.AlignVCenter 在可用空间中,居中显示在垂直方向上
Qt.AlignBaseline 与基线对齐

如果要设置水平和垂直对齐方式,比如在表格空间内上下、左右居中对齐,那么只要使用Qt.AlignHCenter和Qt.AlignVCenter即可。

3. 代码实现

在上一篇文章的基础上加上QTableWidget类


class TableWidgetClass(QWidget):

    def __init__(self, tablewidget):
        # noinspection PyArgumentList
        super(TableWidgetClass, self).__init__()
        self.tableWidget = None
        self.initui(tablewidget)
        self.twrowcnt = 0

    def initui(self, tablewidget):
        # layout = QHBoxLayout()

        self.tableWidget = tablewidget
        self.tableWidget.setColumnCount(4)
        self.tableWidget.setRowCount(0)

        # 设置头label
        self.tableWidget.setHorizontalHeaderLabels(['测试用例', '执行时间', '结果', '备注'])

        # 设置列宽度
        self.tableWidget.setColumnWidth(0, 200)
        self.tableWidget.setColumnWidth(1, 130)
        self.tableWidget.setColumnWidth(2, 100)
        self.tableWidget.setColumnWidth(3, 400)

        # 优化3 将表格变为禁止编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 优化 4 设置表格整行选中
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)

    def table_append(self, str_info):
        if str_info == 'CCO测试项' or str_info == 'STA测试项' or str_info == '协议一致性' \
                or str_info == '通信性能测试' or str_info == 'CCO性能测试项' or str_info == 'STA性能测试项':
            return
        item = self.tableWidget.findItems(str_info, Qt.MatchExactly)
        if not item:
            row = self.tableWidget.rowCount()
            self.tableWidget.insertRow(row)
            newitem = QTableWidgetItem(str_info)
            self.tableWidget.setItem(row, 0, newitem)

    def table_remove(self, str_info):
        item = self.tableWidget.findItems(str_info, Qt.MatchExactly)
        if item:
            row = item[0].row()
            self.tableWidget.removeRow(row)

全部的实现代码如下,同样分为2个文件:

py1 name: treewidget.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'treewidget.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1299, 594)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.treeWidget.sizePolicy().hasHeightForWidth())
        self.treeWidget.setSizePolicy(sizePolicy)
        self.treeWidget.setObjectName("treeWidget")
        self.treeWidget.headerItem().setText(0, "1")
        self.horizontalLayout.addWidget(self.treeWidget)
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(2)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth())
        self.tableWidget.setSizePolicy(sizePolicy)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(0)
        self.tableWidget.setRowCount(0)
        self.horizontalLayout.addWidget(self.tableWidget)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1299, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

py2 name: main.py

# -*- coding: utf-8 -*-

import sys
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
from treewidget import Ui_MainWindow

class AllCertCaseValue:
    ROOT_PROTOCON = 0
    # STA 协议一致性所有case
    ROOT_PROTOCON_STA_CHILD = 1
    # sta scan tmi band0/1/2/3
    ROOT_PROTOCON_STA_TMISCAN_B0 = 2
    ROOT_PROTOCON_STA_TMISCAN_B1 = 3
    ROOT_PROTOCON_STA_TMISCAN_B2 = 4
    ROOT_PROTOCON_STA_TMISCAN_B3 = 5
    # sta tonemask band0/1/2/3
    ROOT_PROTOCON_STA_TM_B0 = 6
    ROOT_PROTOCON_STA_TM_B1 = 7
    ROOT_PROTOCON_STA_TM_B2 = 8
    ROOT_PROTOCON_STA_TM_B3 = 9

    ROOT_PROTOCON_STA_MAX = ROOT_PROTOCON_STA_TM_B3 + 1

    # CCO 协议一致性所有case
    ROOT_PROTOCON_CCO_CHILD = 40
    # cco scan tmi band0/1/2/3
    ROOT_PROTOCON_CCO_TMISCAN_B0 = 41
    ROOT_PROTOCON_CCO_TMISCAN_B1 = 42
    ROOT_PROTOCON_CCO_TMISCAN_B2 = 43
    ROOT_PROTOCON_CCO_TMISCAN_B3 = 44
    # sta tonemask band0/1/2/3
    ROOT_PROTOCON_CCO_TM_B0 = 45
    ROOT_PROTOCON_CCO_TM_B1 = 46
    ROOT_PROTOCON_CCO_TM_B2 = 47
    ROOT_PROTOCON_CCO_TM_B3 = 48

    ROOT_PROTOCON_CCO_MAX = ROOT_PROTOCON_CCO_TM_B3 + 1

    # 通信性能测试
    ROOT_PERFORMANCE_CHILD = 80
    ROOT_PERFORMANCE_STA_CHILD = 81

    # white noise
    ROOT_PERFORMANCE_STA_WN_B1 = 82
    ROOT_PERFORMANCE_STA_WN_B2 = 83
    # anti-ppm
    ROOT_PERFORMANCE_STA_ANTIPPM_B1 = 84
    ROOT_PERFORMANCE_STA_ANTIPPM_B2 = 85
    # anti-attenuation
    ROOT_PERFORMANCE_STA_ANTIATT_B1 = 86
    ROOT_PERFORMANCE_STA_ANTIATT_B2 = 87
    # anti-narrowband
    ROOT_PERFORMANCE_STA_ANTINARROW_B1 = 88
    ROOT_PERFORMANCE_STA_ANTINARROW_B2 = 89
    # anti-pulse
    ROOT_PERFORMANCE_STA_ANTIPULSE_B1 = 90
    ROOT_PERFORMANCE_STA_ANTIPULSE_B2 = 91
    # psd
    ROOT_PERFORMANCE_STA_PSD_B1 = 92
    ROOT_PERFORMANCE_STA_PSD_B2 = 93
    # sta rate
    ROOT_PERFORMANCE_STA_RATE_B1 = 94
    ROOT_PERFORMANCE_STA_RATE_B2 = 95

    ROOT_PERFORMANCE_STA_MAX = ROOT_PERFORMANCE_STA_RATE_B2 + 1

    ROOT_PERFORMANCE_CCO_CHILD = 100
    # white noise
    ROOT_PERFORMANCE_CCO_WN_B1 = 101
    ROOT_PERFORMANCE_CCO_WN_B2 = 102
    # anti-ppm
    ROOT_PERFORMANCE_CCO_ANTIPPM_B1 = 103
    ROOT_PERFORMANCE_CCO_ANTIPPM_B2 = 104
    # anti-attenuation
    ROOT_PERFORMANCE_CCO_ANTIATT_B1 = 105
    ROOT_PERFORMANCE_CCO_ANTIATT_B2 = 106
    # anti-narrowband
    ROOT_PERFORMANCE_CCO_ANTINARROW_B1 = 107
    ROOT_PERFORMANCE_CCO_ANTINARROW_B2 = 108
    # anti-pulse
    ROOT_PERFORMANCE_CCO_ANTIPULSE_B1 = 109
    ROOT_PERFORMANCE_CCO_ANTIPULSE_B2 = 110
    # psd
    ROOT_PERFORMANCE_CCO_PSD_B1 = 111
    ROOT_PERFORMANCE_CCO_PSD_B2 = 112
    # CCO rate
    ROOT_PERFORMANCE_CCO_RATE_B1 = 113
    ROOT_PERFORMANCE_CCO_RATE_B2 = 114
    ROOT_PERFORMANCE_CCO_MAX = ROOT_PERFORMANCE_CCO_RATE_B2 + 1

    ROOT_OTHER_CHILD = 130
    ROOT_OTHER_RATE = 131
    ROOT_OTHER_MAX = ROOT_OTHER_RATE + 1

    # max
    TREE_MAX = ROOT_OTHER_MAX + 1


DictCommandInfo = {
    "协议一致性": AllCertCaseValue.ROOT_PROTOCON,
    # STA test case
    "STA测试项": AllCertCaseValue.ROOT_PROTOCON_STA_CHILD,
    "TMI遍历 STA band0": AllCertCaseValue.ROOT_PROTOCON_STA_TMISCAN_B0,
    "TMI遍历 STA band1": AllCertCaseValue.ROOT_PROTOCON_STA_TMISCAN_B1,
    "TMI遍历 STA band2": AllCertCaseValue.ROOT_PROTOCON_STA_TMISCAN_B2,
    "TMI遍历 STA band3": AllCertCaseValue.ROOT_PROTOCON_STA_TMISCAN_B3,
    "ToneMask测试 STA band0": AllCertCaseValue.ROOT_PROTOCON_STA_TM_B0,
    "ToneMask测试 STA band1": AllCertCaseValue.ROOT_PROTOCON_STA_TM_B1,
    "ToneMask测试 STA band2": AllCertCaseValue.ROOT_PROTOCON_STA_TM_B2,
    "ToneMask测试 STA band3": AllCertCaseValue.ROOT_PROTOCON_STA_TM_B3,

    # CCO test case
    "CCO测试项": AllCertCaseValue.ROOT_PROTOCON_CCO_CHILD,
    "TMI遍历 CCO band0": AllCertCaseValue.ROOT_PROTOCON_CCO_TMISCAN_B0,
    "TMI遍历 CCO band1": AllCertCaseValue.ROOT_PROTOCON_CCO_TMISCAN_B1,
    "TMI遍历 CCO band2": AllCertCaseValue.ROOT_PROTOCON_CCO_TMISCAN_B2,
    "TMI遍历 CCO band3": AllCertCaseValue.ROOT_PROTOCON_CCO_TMISCAN_B3,
    "ToneMask测试 CCO band0": AllCertCaseValue.ROOT_PROTOCON_CCO_TM_B0,
    "ToneMask测试 CCO band1": AllCertCaseValue.ROOT_PROTOCON_CCO_TM_B1,
    "ToneMask测试 CCO band2": AllCertCaseValue.ROOT_PROTOCON_CCO_TM_B2,
    "ToneMask测试 CCO band3": AllCertCaseValue.ROOT_PROTOCON_CCO_TM_B3,

    # communication performance
    "通信性能测试": AllCertCaseValue.ROOT_PERFORMANCE_CHILD,
    "STA性能测试项": AllCertCaseValue.ROOT_PERFORMANCE_STA_CHILD,
    "白噪性能 STA band1": AllCertCaseValue.ROOT_PERFORMANCE_STA_WN_B1,
    "白噪性能 STA band2": AllCertCaseValue.ROOT_PERFORMANCE_STA_WN_B2,
    "抗频偏性能 STA band1": AllCertCaseValue.ROOT_PERFORMANCE_STA_ANTIPPM_B1,
    "抗频偏性能 STA band2": AllCertCaseValue.ROOT_PERFORMANCE_STA_ANTIPPM_B2,
    "抗衰减性能 STA band1": AllCertCaseValue.ROOT_PERFORMANCE_STA_ANTIATT_B1,
    "抗衰减性能 STA band2": AllCertCaseValue.ROOT_PERFORMANCE_STA_ANTIATT_B2,
    "抗窄带性能 STA band1": AllCertCaseValue.ROOT_PERFORMANCE_STA_ANTINARROW_B1,
    "抗窄带性能 STA band2": AllCertCaseValue.ROOT_PERFORMANCE_STA_ANTINARROW_B2,
    "抗脉冲性能 STA band1": AllCertCaseValue.ROOT_PERFORMANCE_STA_ANTIPULSE_B1,
    "抗脉冲性能 STA band2": AllCertCaseValue.ROOT_PERFORMANCE_STA_ANTIPULSE_B2,
    "功率频谱密度 STA band1": AllCertCaseValue.ROOT_PERFORMANCE_STA_PSD_B1,
    "功率频谱密度 STA band2": AllCertCaseValue.ROOT_PERFORMANCE_STA_PSD_B2,
    "STA 速率测试 band1": AllCertCaseValue.ROOT_PERFORMANCE_STA_RATE_B1,
    "STA 速率测试 band2": AllCertCaseValue.ROOT_PERFORMANCE_STA_RATE_B2,
    "CCO性能测试项": AllCertCaseValue.ROOT_PERFORMANCE_CCO_CHILD,
    "白噪性能 CCO band1": AllCertCaseValue.ROOT_PERFORMANCE_CCO_WN_B1,
    "白噪性能 CCO band2": AllCertCaseValue.ROOT_PERFORMANCE_CCO_WN_B2,
    "抗频偏性能 CCO band1": AllCertCaseValue.ROOT_PERFORMANCE_CCO_ANTIPPM_B1,
    "抗频偏性能 CCO band2": AllCertCaseValue.ROOT_PERFORMANCE_CCO_ANTIPPM_B2,
    "抗衰减性能 CCO band1": AllCertCaseValue.ROOT_PERFORMANCE_CCO_ANTIATT_B1,
    "抗衰减性能 CCO band2": AllCertCaseValue.ROOT_PERFORMANCE_CCO_ANTIATT_B2,
    "抗窄带性能 CCO band1": AllCertCaseValue.ROOT_PERFORMANCE_CCO_ANTINARROW_B1,
    "抗窄带性能 CCO band2": AllCertCaseValue.ROOT_PERFORMANCE_CCO_ANTINARROW_B2,
    "抗脉冲性能 CCO band1": AllCertCaseValue.ROOT_PERFORMANCE_CCO_ANTIPULSE_B1,
    "抗脉冲性能 CCO band2": AllCertCaseValue.ROOT_PERFORMANCE_CCO_ANTIPULSE_B2,
    "功率频谱密度 CCO band1": AllCertCaseValue.ROOT_PERFORMANCE_CCO_PSD_B1,
    "功率频谱密度 CCO band2": AllCertCaseValue.ROOT_PERFORMANCE_CCO_PSD_B2,
    "CCO 速率测试 band1": AllCertCaseValue.ROOT_PERFORMANCE_CCO_RATE_B1,
    "CCO 速率测试 band2": AllCertCaseValue.ROOT_PERFORMANCE_CCO_RATE_B2,

    # other test case
    "OTHER_TEST": AllCertCaseValue.ROOT_OTHER_CHILD,
    "RATE TEST": AllCertCaseValue.ROOT_OTHER_RATE,
}

class tree(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self):
        super(tree, self).__init__()
        self.setupUi(self)
        self.AllTestCase = None
        self.intiui()

    def intiui(self):
        # 初始化tablewidget模块
        self.tw = TableWidgetClass(self.tableWidget)

        # 设置列数
        self.treeWidget.setColumnCount(1)
        # 设置树形控件头部的标题
        self.treeWidget.setHeaderLabels(['测试用例'])
        self.treeWidget.setColumnWidth(0, 120)

        # 设置根节点
        self.AllTestCase = QTreeWidgetItem(self.treeWidget)
        self.AllTestCase.setText(0, '测试项')
        self.AllTestCase.setCheckState(0, Qt.Unchecked)

        # sg
        for value in DictCommandInfo.keys():
            if DictCommandInfo[value] == AllCertCaseValue.ROOT_PROTOCON:
                item_protocon = QTreeWidgetItem(self.AllTestCase)
                item_protocon.setText(0, value)
                item_protocon.setCheckState(0, Qt.Unchecked)
            elif DictCommandInfo[value] == AllCertCaseValue.ROOT_PROTOCON_STA_CHILD:
                item_sta_father = QTreeWidgetItem(item_protocon)
                item_sta_father.setText(0, value)
                item_sta_father.setCheckState(0, Qt.Unchecked)
            elif (AllCertCaseValue.ROOT_PROTOCON_STA_CHILD < DictCommandInfo[value] <
                  AllCertCaseValue.ROOT_PROTOCON_STA_MAX):
                item_sta_child = QTreeWidgetItem(item_sta_father)
                item_sta_child.setText(0, value)
                item_sta_child.setCheckState(0, Qt.Unchecked)
            elif DictCommandInfo[value] == AllCertCaseValue.ROOT_PROTOCON_CCO_CHILD:
                item_cco_father = QTreeWidgetItem(item_protocon)
                item_cco_father.setText(0, value)
                item_cco_father.setCheckState(0, Qt.Unchecked)
            elif (AllCertCaseValue.ROOT_PROTOCON_CCO_CHILD < DictCommandInfo[value] <
                  AllCertCaseValue.ROOT_PROTOCON_CCO_MAX):
                item_cco_child = QTreeWidgetItem(item_cco_father)
                item_cco_child.setText(0, value)
                item_cco_child.setCheckState(0, Qt.Unchecked)
            elif DictCommandInfo[value] == AllCertCaseValue.ROOT_PERFORMANCE_CHILD:
                item_prerf_father = QTreeWidgetItem(self.AllTestCase)
                item_prerf_father.setText(0, value)
                item_prerf_father.setCheckState(0, Qt.Unchecked)
            elif DictCommandInfo[value] == AllCertCaseValue.ROOT_PERFORMANCE_STA_CHILD:
                item_prerf_sta_father = QTreeWidgetItem(item_prerf_father)
                item_prerf_sta_father.setText(0, value)
                item_prerf_sta_father.setCheckState(0, Qt.Unchecked)
            elif (AllCertCaseValue.ROOT_PERFORMANCE_STA_CHILD < DictCommandInfo[value] <
                  AllCertCaseValue.ROOT_PERFORMANCE_STA_MAX):
                item_perf_sta_child = QTreeWidgetItem(item_prerf_sta_father)
                item_perf_sta_child.setText(0, value)
                item_perf_sta_child.setCheckState(0, Qt.Unchecked)
            elif DictCommandInfo[value] == AllCertCaseValue.ROOT_PERFORMANCE_CCO_CHILD:
                item_prerf_cco_father = QTreeWidgetItem(item_prerf_father)
                item_prerf_cco_father.setText(0, value)
                item_prerf_cco_father.setCheckState(0, Qt.Unchecked)
            elif (AllCertCaseValue.ROOT_PERFORMANCE_CCO_CHILD < DictCommandInfo[value] <
                  AllCertCaseValue.ROOT_PERFORMANCE_CCO_MAX):
                item_perf_cco_child = QTreeWidgetItem(item_prerf_cco_father)
                item_perf_cco_child.setText(0, value)
                item_perf_cco_child.setCheckState(0, Qt.Unchecked)
            elif DictCommandInfo[value] == AllCertCaseValue.ROOT_OTHER_CHILD:
                item_other_father = QTreeWidgetItem(self.AllTestCase)
                item_other_father.setText(0, value)
                item_other_father.setCheckState(0, Qt.Unchecked)
            elif AllCertCaseValue.ROOT_OTHER_CHILD < DictCommandInfo[value] < \
                    AllCertCaseValue.ROOT_OTHER_MAX:
                item_other_child = QTreeWidgetItem(item_other_father)
                item_other_child.setText(0, value)
                item_other_child.setCheckState(0, Qt.Unchecked)

        # 节点全部展开
        self.treeWidget.expandAll()

        self.treeWidget.itemChanged.connect(self.handlechanged)

    def handlechanged(self, item, column):
        count = item.childCount()
        if item.checkState(column) == Qt.Checked:
            if count == 0:
                self.tw.table_append(item.text(0))
            for f in range(count):
                if item.child(f).checkState(0) != Qt.Checked:
                    item.child(f).setCheckState(0, Qt.Checked)
                    self.tw.table_append(item.child(f).text(0))

        if item.checkState(column) == Qt.Unchecked:
            if count == 0:
                self.tw.table_remove(item.text(0))
            for f in range(count):
                if item.child(f).checkState != Qt.Unchecked:
                    item.child(f).setCheckState(0, Qt.Unchecked)
                    self.tw.table_remove(item.text(0))

class TableWidgetClass(QWidget):

    def __init__(self, tablewidget):
        # noinspection PyArgumentList
        super(TableWidgetClass, self).__init__()
        self.tableWidget = None
        self.initui(tablewidget)
        self.twrowcnt = 0

    def initui(self, tablewidget):
        # layout = QHBoxLayout()

        self.tableWidget = tablewidget
        self.tableWidget.setColumnCount(4)
        self.tableWidget.setRowCount(0)

        # 设置头label
        self.tableWidget.setHorizontalHeaderLabels(['测试用例', '执行时间', '结果', '备注'])

        # 设置列宽度
        self.tableWidget.setColumnWidth(0, 200)
        self.tableWidget.setColumnWidth(1, 130)
        self.tableWidget.setColumnWidth(2, 100)
        self.tableWidget.setColumnWidth(3, 400)

        # 优化3 将表格变为禁止编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 优化 4 设置表格整行选中
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)

    def table_append(self, str_info):
        if str_info == 'CCO测试项' or str_info == 'STA测试项' or str_info == '协议一致性' \
                or str_info == '通信性能测试' or str_info == 'CCO性能测试项' or str_info == 'STA性能测试项':
            return
        item = self.tableWidget.findItems(str_info, Qt.MatchExactly)
        if not item:
            row = self.tableWidget.rowCount()
            self.tableWidget.insertRow(row)
            newitem = QTableWidgetItem(str_info)
            self.tableWidget.setItem(row, 0, newitem)

    def table_remove(self, str_info):
        item = self.tableWidget.findItems(str_info, Qt.MatchExactly)
        if item:
            row = item[0].row()
            self.tableWidget.removeRow(row)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    myshow = tree()
    myshow.show()
    sys.exit(app.exec_())

以上代码可以实现图片上的功能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pyqt5 tableWidget入门,和treewidget联动功能 的相关文章

  • 是否有解决方法可以通过 CoinGecko API 安全检查?

    我在工作中运行我的代码 一切都很顺利 但在不同的网络 家庭 WiFi 上 我不断收到403访问时出错CoinGecko V3 API https www coingecko com api documentations v3 可以观察到 在
  • Django 的内联管理:一个“预填充”字段

    我正在开发我的第一个 Django 项目 我希望用户能够在管理中创建自定义表单 并向其中添加字段当他或她需要它们时 为此 我在我的项目中添加了一个可重用的应用程序 可在 github 上找到 https github com stephen
  • 使用特定的类/函数预加载 Jupyter Notebook

    我想预加载一个笔记本 其中包含我在另一个文件中定义的特定类 函数 更具体地说 我想用 python 来做到这一点 比如加载一个配置文件 包含所有相关的类 函数 目前 我正在使用 python 生成笔记本并在服务器上自动启动它们 因为不同的
  • 处理 Python 行为测试框架中的异常

    我一直在考虑从鼻子转向行为测试 摩卡 柴等已经宠坏了我 到目前为止一切都很好 但除了以下之外 我似乎无法找出任何测试异常的方法 then It throws a KeyError exception def step impl contex
  • Pandas 日期时间格式

    是否可以用零后缀表示 pd to datetime 似乎零被删除了 print pd to datetime 2000 07 26 14 21 00 00000 format Y m d H M S f 结果是 2000 07 26 14
  • 独立滚动矩阵的行

    我有一个矩阵 准确地说 是 2d numpy ndarray A np array 4 0 0 1 2 3 0 0 5 我想滚动每一行A根据另一个数组中的滚动值独立地 r np array 2 0 1 也就是说 我想这样做 print np
  • 您可以格式化 pandas 整数以进行显示,例如浮点数的“pd.options.display.float_format”?

    我见过this https stackoverflow com questions 18404946 py pandas formatdataframe and this https stackoverflow com questions
  • datetime.datetime.now() 返回旧值

    我正在通过匹配日期查找 python 中的数据存储条目 我想要的是每天选择 今天 的条目 但由于某种原因 当我将代码上传到 gae 服务器时 它只能工作一天 第二天它仍然返回相同的值 例如当我上传代码并在 07 01 2014 执行它时 它
  • 使用 xlrd 打开 BytesIO (xlsx)

    我正在使用 Django 需要读取上传的 xlsx 文件的工作表和单元格 使用 xlrd 应该可以 但因为文件必须保留在内存中并且可能不会保存到我不知道如何继续的位置 本例中的起点是一个带有上传输入和提交按钮的网页 提交后 文件被捕获req
  • 如何在不丢失注释和格式的情况下更新 YAML 文件 / Python 中的 YAML 自动重构

    我想在 Python 中更新 YAML 文件值 而不丢失 Python 中的格式和注释 例如我想改造 YAML 文件 value 456 nice value to value 6 nice value 界面类似于 y yaml load
  • “隐藏”内置类对象、函数、代码等的名称和性质[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我很好奇模块中存在的类builtins无法直接访问的 例如 type lambda 0 name function of module
  • 如何通过索引列表从 dask 数据框中选择数据?

    我想根据索引列表从 dask 数据框中选择行 我怎样才能做到这一点 Example 假设我有以下 dask 数据框 dict A 1 2 3 4 5 6 7 B 2 3 4 5 6 7 8 index x1 a2 x3 c4 x5 y6 x
  • Numpy - 根据表示一维的坐标向量的条件替换数组中的值

    我有一个data多维数组 最后一个是距离 另一方面 我有距离向量r 例如 Data np ones 20 30 100 r np linspace 10 50 100 最后 我还有一个临界距离值列表 称为r0 使得 r0 shape Dat
  • javascript 是否有等效的 __repr__ ?

    我最接近Python的东西repr这是 function User name password this name name this password password User prototype toString function r
  • Jupyter Notebook 找不到 Python 模块

    不知道发生了什么 但每当我使用 ipython 氢 原子 或 jupyter 笔记本时都找不到任何已安装的模块 我知道我安装了 pandas 但笔记本说找不到 我应该补充一点 当我正常运行脚本时 python script py 它确实导入
  • 仅第一个加载的 Django 站点有效

    我最近向 stackoverflow 提交了一个问题 标题为使用mod wsgi在apache上多次请求后Django无限加载 https stackoverflow com questions 71705909 django infini
  • 使用特定颜色和抖动在箱形图上绘制数据点

    我有一个plotly graph objects Box图 我显示了箱形 图中的所有点 我需要根据数据的属性为标记着色 如下所示 我还想抖动这些点 下面未显示 Using Box我可以绘制点并抖动它们 但我不认为我可以给它们着色 fig a
  • 根据列 value_counts 过滤数据框(pandas)

    我是第一次尝试熊猫 我有一个包含两列的数据框 user id and string 每个 user id 可能有多个字符串 因此会多次出现在数据帧中 我想从中导出另一个数据框 一个只有那些user ids列出至少有 2 个或更多string
  • 模拟pytest中的异常终止

    我的多线程应用程序遇到了一个错误 主线程的任何异常终止 例如 未捕获的异常或某些信号 都会导致其他线程之一死锁 并阻止进程干净退出 我解决了这个问题 但我想添加一个测试来防止回归 但是 我不知道如何在 pytest 中模拟异常终止 如果我只
  • Scipy Sparse:SciPy/NumPy 更新后出现奇异矩阵警告

    我的问题是由大型电阻器系统的节点分析产生的 我基本上是在设置一个大的稀疏矩阵A 我的解向量b 我正在尝试求解线性方程A x b 为了做到这一点 我正在使用scipy sparse linalg spsolve method 直到最近 一切都

随机推荐

  • ‘git‘不是内部或外部命令及Git 的保姆级安装教程(保姆级教程)

    目录 一 问题出自何方 二 Git的下载 三 安装 浅浅记录下使用Git中遇到的坑 文章来自Git 的安装教程 详解每个步骤 Passerby Wang的博客 CSDN博客 安装gitGit 的下载与安装一 下载1 下载Git登陆git官网
  • ESP32 之 ESP-IDF 教学(十八)—— 组件配置(KConfig)

    本文章 来自原创专栏 ESP32教学专栏 基于ESP IDF 讲解如何使用 ESP IDF 构建 ESP32 程序 发布文章并会持续为已发布文章添加新内容 每篇文章都经过了精打细磨 通过下方对话框进入专栏目录页 CSDN 请求进入目录 O
  • React 路由详解(超详细详解)

    React React 路由 对SPA的理解 1 单页Web应用 single page web application SPA 2 整个应用只有一个完整的页面 3 点击页面中的链接不会刷新页面 只会做页面的局部更新 4 数据都需要通过aj
  • C++中前置声明的应用与陷阱

    前置声明的使用 有一定C 开发经验的朋友可能会遇到这样的场景 两个类A与B是强耦合关系 类A要引用B的对象 类B也要引用类A的对象 好的 不难 我的第一直觉让我写出这样的代码 A h include B h class A B b publ
  • Vue CLI创建新项目,并运行

    1 准备工作 创建项目之前 我们需要知道在哪里创建 第一种 找到创建的文件 打开cmd方法 第二种方法 1 打开需要创建vue项目的文件下 按住shift 鼠标右键 2 点击 此处打开Powershell命令 2 安装vue cli脚手架
  • html 下拉列表对齐,HTML下拉元素宽度未与兄弟姐妹对齐

    你应该使用display inline block而不是float left in list item css 并且应该添加display table row 进入 子列表项目 dark blue 31394C light gray E6E
  • Altium Designer 报错整理-软件安装失败

    一 软件安装问题 安装问题描述一 关于软件安装 安装到进行到最后一步 显示Optimizing startup performance please wait 然后就一直卡住停留在这一步 无法进行下一步 尝试的办法 低版本 安装问题依旧 管
  • IDEA下载安装及配置

    IntelliJ IDEA 的安装 配置与使用 根据尚硅谷进行整理 仅仅只做笔记 根据尚硅谷进行整理 仅仅只做笔记 根据尚硅谷进行整理 仅仅只做笔记 一 IDEA 的下载地址 下载地址 https www jetbrains com ide
  • git命令学习(三)

    merge和rebase的区别 git工作流 git stash 使用场景举例 一个分支还没提交时 要切换到下一个分支 可将前一个分支放在git栈中 git stash git checkout B 处理B分支 git checkout A
  • openlayers3开发教程_开始

    openlayers3开发教程 开始 openlayers官方网站 https openlayers org 在旧版本处查看 Latest v3 v3 20 1 released 2016 12 12 docs API examples o
  • switch手柄可以连电脑吗_你想要的手柄:既能连switch又能连PC!

    您好 我是Manta科技资讯 首先 聊一聊任天堂switch 任天堂switch主机模式下是通过DOCK底座将游戏主机与电视连接以实现无缝切换 这个DOCK底座有2个USB接口 很多小伙伴不知道用它来干嘛 其实DOCK底座能够拓展很多额外的
  • kettle plugin 插件开发

    http wiki pentaho com display COM PDI Plugin Loading svn source pentaho org svnkettleroot plugins S3CsvInput
  • HDU - 1716 排列2(暴力;next_permutation)

    Ray又对数字的列产生了兴趣 现有四张卡片 用这四张卡片能排列出很多不同的4位数 要求按从小到大的顺序输出这些4位数 Input 每组数据占一行 代表四张卡片上的数字 0 lt 数字 lt 9 如果四张卡片都是0 则输入结束 Output
  • Win11打不开Windows安全中心

    1 打开Windows PowerShell ISE 在搜索框内搜索windows powershell ise 然后右击以管理员身份运行 2 依次执行如下3个命令即可 中途出现部署失败的红色提示可以无视 整个过程几分钟 复制回车 Set
  • bootstrap-table动态合并相同行和列的方法

    先看看效果 var getData ctx demo table list table bootstrapTable dataType json method post cache false url getData columns che
  • 详解JPEG编码格式

    参考文章1 参考文章2 MJPEG是一种视频压缩格式 其中的每一帧图像都使用JPEG编码 实际上 M J P E G
  • JS逆向-百度翻译sign

    前言 本文是该专栏的第36篇 后面会持续分享python爬虫干货知识 记得关注 有粉丝留言 近期需要做个翻译功能 考虑到百度翻译语言语种比较全面 但是它的参数被逆向加密了 对于这种情况需要怎么处理呢 所以本文以它为例 废话不多说 跟着笔者直
  • uniapp实现小程序云开发

    打开微信开发者工具 填写你的appid 勾选使用云开发 对应的uniapp里也要配置上你的appid喔 在这个文件manifest json 我在App vue页面 不一定是在这个页面 可以视你的情况而定 里调用 了wx cloud ini
  • JavaScript算法之动态规划

    动态规划的基本概念 动态规划 Dynamic Programming DP 是运筹学的一个分支 是求解决策过程最优化的过程 动态规划算法通常用于求解具有某种最优性质的问题 在这类问题中 可能会有许多可行解 每一个解都对应于一个值 我们希望找
  • pyqt5 tableWidget入门,和treewidget联动功能

    1 成品 最近在做项目的过程中需要用到QTreeWidget和QTableWidget联动 上一篇文章介绍了 QTreeWidget的基本用法 这里介绍一下QTableWidget的基本用法 及我在项目中的使用 先看看最终成品 要实现以上图