weixin_44532019 2022-11-15 12:23 采纳率: 68.2%
浏览 31
已结题

pyqt5 QStandardItemModel 复选框

在pyqt5 中 QStandardItemModel 创建了一个 表格, 想在表格中加入 复选框。 全选多选 那种。 找了好多材料都没有找到 。 有没有同学碰到过这种问题呀。

用代码块功能插入代码,请勿粘贴截图

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import  sql_mok
import sys

class Table(QWidget):
    def __init__(self,arg = None):
        super(Table, self).__init__(arg)
        self.setWindowTitle("QTableView表格视图控件案例")
        self.resize(500 , 300)


        sql = sql_mok.sql_mokuai()
        sql_jb = sql.huoqucanshu()

        data = sql.sql_select_pl(sql_jb["xsdd"])


        self.model = QStandardItemModel(1,1)

        self.model.setHorizontalHeaderLabels(["id","平台单号","下单日期","客户名称","总金额","手机号","收货人","收货地址","快递单号",""])


        for i,j in enumerate(data):
            # print(j)
            # tup1 = list(j)
            # tup1.append(QCheckBox())
            # j = tup1
            # j =  tuple(j)
            # print(j)

            for h,z in enumerate(j):
                item = QStandardItem(z)
                # print(i, h,z)
                self.model.setItem(i, h, item)


        # self.model.appendRow([item1, item2, item3, item4, item5])

        self.tableView = QTableView()
        self.tableView.setModel(self.model)

        frm = QFrame()
        dlgLayout = QVBoxLayout(frm)
        dlgLayout.addWidget(self.tableView)
        self.setLayout(dlgLayout)



if __name__ == '__main__':

    app = QApplication(sys.argv)
    win = Table()
    win.show()
    sys.exit(app.exec_())

img

  • 写回答

6条回答 默认 最新

  • Jackyin0720 2022-11-15 14:58
    关注
    
    #-*- coding: utf-8 -*-
    from PySide2.QtUiTools import *
    from PySide2.QtWidgets import *
    from PySide2.QtGui import *
    from PySide2.QtCore import *
    import sys
    
    all_header_checkbox =[]
    
    #设置列不可编辑类
    class EmptyDelegate(QItemDelegate):
        def __init__(self,parent):
            super(EmptyDelegate, self).__init__(parent)
        def createEditor(self, QWidget, QStyleOptionViewItem, QModelIndex):
            return None
    #表格类
    class qtableDelete():
        def __init__(self):
            self.ui = QUiLoader().load('ui/qtable_delete.ui')
            self.settable()
            self.ui.delete_2.clicked.connect(self.delete_check)
            
        #设置表格内容
        def settable(self):
            header = CheckBoxHeader()
            self.ui.table.setHorizontalHeader(header) # 设置头复选框
            header.select_all_clicked.connect(header.change_state)  # 行表头复选框单击信号与槽
            self.ui.table.setSelectionBehavior(QAbstractItemView.SelectRows)  # 设置整行选中
            # self.ui.table.setSelectionMode(QAbstractItemView.SingleSelection)#设置选择模式,选择单行
            self.ui.table.setRowCount(15)  # 设置表格行数
            self.ui.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)  # 设置表头自适应
            #设置表格内容和复选框
            for i in range(15):
                checkbox = QCheckBox()
                all_header_checkbox.append(checkbox)
                # checkbox.setCheckState(Qt.Unchecked) #设置复选框为不选状态、Partially(半选)、Checked(全选)
                self.ui.table.setCellWidget(i, 0, checkbox)  # 设置表格可选项
                for j in range(5):
                    self.ui.table.setItem(i, j, QTableWidgetItem(f'{i}row,{j}col'))
    
                    self.ui.table.item(i, j).setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)  # 设置表格内水平垂直居#设置指定列的颜色和下划线
            #设置第4列样式
            for i in range(self.ui.table.rowCount()):
                self.ui.table.item(i, 3).setForeground(QBrush(QColor('Blue'))) #设置颜色
                font = QFont()
                font.setUnderline(True)
                self.ui.table.item(i, 3).setFont(font)#设置下划线
    
            #设置第1/2/3、5列不可编辑
            list = [1, 2, 0, 4]
            for i in list:
                self.ui.table.setItemDelegateForColumn(i, EmptyDelegate(self.ui))
    
    #删除选中的行数
        def delete_check(self):
            row_box_list = []
            # 获取选中数据
            for i in range(self.ui.table.rowCount()):
                if self.ui.table.cellWidget(i, 0).isChecked() is True:
                    row_box_list.append(i)
                    row_box_list.reverse()  # 将数据进行降序
            for j in row_box_list:
                self.ui.table.removeRow(j)  # 删除选中行数据
                all_header_checkbox.pop(j)  # 重新构建check box列表
    
    class CheckBoxHeader(QHeaderView):
        """自定义表头类"""
        # 自定义 复选框全选信号
        select_all_clicked = Signal(bool)
        # 这4个变量控制列头复选框的样式,位置以及大小
        _x_offset = 0
        _y_offset = 0
        _width = 20
        _height = 20
    
        def __init__(self, orientation=Qt.Horizontal, parent=None):
            super(CheckBoxHeader, self).__init__(orientation, parent)
            self.isOn = False
    
        def paintSection(self, painter, rect, logicalIndex):
            painter.save()
            super(CheckBoxHeader, self).paintSection(painter, rect, logicalIndex)
            painter.restore()
    
            self._y_offset = int((rect.height() - self._width) / 2.)
    
            if logicalIndex == 0:
                option = QStyleOptionButton()
                option.rect = QRect(rect.x() + self._x_offset, rect.y() + self._y_offset, self._width, self._height)
                option.state = QStyle.State_Enabled | QStyle.State_Active
                if self.isOn:
                    option.state |= QStyle.State_On
                else:
                    option.state |= QStyle.State_Off
                self.style().drawControl(QStyle.CE_CheckBox, option, painter)
    
        def mousePressEvent(self, event):
            index = self.logicalIndexAt(event.pos())
            if 0 == index:
                x = self.sectionPosition(index)
                if x + self._x_offset < event.pos().x() < x + self._x_offset + self._width and self._y_offset < event.pos().y() < self._y_offset + self._height:
                    if self.isOn:
                        self.isOn = False
                    else:
                        self.isOn = True
                        # 当用户点击了行表头复选框,发射 自定义信号 select_all_clicked()
                    self.select_all_clicked.emit(self.isOn)
    
                    self.updateSection(0)
            super(CheckBoxHeader, self).mousePressEvent(event)
    
        # 自定义信号 select_all_clicked 的槽方法
        def change_state(self, isOn):
            # 如果行表头复选框为勾选状态
            if isOn:
                # 将所有的复选框都设为勾选状态
                for i in all_header_checkbox:
                    i.setCheckState(Qt.Checked)
            else:
                for i in all_header_checkbox:
                    i.setCheckState(Qt.Unchecked)
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        stats = qtableDelete()
        stats.ui.show()
        app.exec_()
    

    【代码仅供参考】
    效果图:

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 11月25日
  • 已采纳回答 11月17日
  • 赞助了问题酬金15元 11月15日
  • 创建了问题 11月15日

悬赏问题

  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line