QTableWidget 复选框,qheadview添加复选框

qtablewidget有复选框功能,有时候想改变复选框位置或大小,就需要自己去绘制了。从网上找了很多实现方法,自己选了其中一个。

1、先写表格中添加复选框

先说明一下:

不说头文件了。

在 InsertTable 函数 和 setCheckBox 函数中都有 QCheckBox::stateChanged 的槽函数实现,自己根据情况选用。

部分主要函数:

  1 //初始化
  2 void DlgTableWidget::InitTable()
  3 {
  4     ui->tableWidget->horizontalHeader()->setVisible(true);
  5     ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//禁止编辑
  6     ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//选择整行
  7     ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
  8     ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
  9     ui->tableWidget->verticalHeader()->setVisible(false);
 10 
 11     ui->tableWidget->setColumnCount(4);
 12     ui->tableWidget->setRowCount(0);
 13 
 14     ui->tableWidget->setStyleSheet("QTableWidget::indicator {width: 40px;height: 40px;}");//QTableWidget::indicator:unchecked {image: url(:/icon/unchecked.png);}QTableWidget::indicator:checked {image: url(:/icon/checked.png);}");
 15 
 16     ui->tableWidget->horizontalHeader()->setMinimumHeight(80);
 17     ui->tableWidget->horizontalHeader()->setStretchLastSection(true);//最后一列自动充满
 18     ui->tableWidget->horizontalHeader()->setVisible(true);
 19     ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);//平均分配列宽
 20     ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{border:0px solid rgb(218, 222, 226);background-color: rgb(204, 217, 230);font: 11pt '微软雅黑'}");
 21 
 22     //bool b = connect(ui->tableWidget,&QTableWidget::cellChanged,this,&DlgTableWidget::SlotChangeCheckbox);
 23     //设置表头
 24     QStringList header;
 25     header << tr("") << tr("检测对象") << tr("检测项目") << tr("状态描述");
 26     ui->tableWidget->setHorizontalHeaderLabels(header);
 27     QStringList list ;
 28     list << "" << "对象" << "项目" << "描述";// << <<;
 29     for (int i = 0; i < 10; i++) {
 30         InsertTable(list);
 31     }
 32 }
 33 
 34 //插入数据
 35 void DlgTableWidget::InsertTable(QStringList &listInfo)
 36 {
 37     int nRowCount = ui->tableWidget->rowCount();
 38     ui->tableWidget->setRowCount(nRowCount + 1);
 39 
 40     QTableWidgetItem* item;// = new QTableWidgetItem(QString("%1").arg(nRowCount + 1));
 41 
 42     for(int i = 0; i < listInfo.size(); i++)
 43     {
 44         item = new QTableWidgetItem(listInfo.at(i));
 45         item->setTextAlignment(Qt::AlignCenter);
 46         if(i == 0){
 47             QCheckBox* pCheckBox = setCheckBox(ui->tableWidget,nRowCount, 0, false);
 48             bool b = connect(pCheckBox, &QCheckBox::stateChanged, this, &DlgTableWidget::SlotSetChecked);
 49             int i = 1;
 50             //item->setCheckState(Qt::Unchecked);
 51             //ui->tableWidget->setItem(nRowCount, i, item);
 52             //SetCheckbox(nRowCount);
 53         }
 54         else {
 55             ui->tableWidget->setItem(nRowCount, i, item);
 56         }
 57     }
 58 }
 59 
 60 //获取CheckBox
 61 QCheckBox* DlgTableWidget::getCheckBox(QTableWidget*table,int row ,int column)
 62 {
 63     QWidget* pWidget = 0;
 64     pWidget = table->cellWidget(row,column); //找到单元格
 65     QCheckBox *pCheckBox = 0;
 66     bool bNew = true;
 67     if(pWidget != 0) //
 68     {
 69         bNew = false;
 70     }
 71     if(bNew)
 72     {
 73         pWidget = new QWidget(table); //创建一个widget
 74         QHBoxLayout *hLayout = new QHBoxLayout(pWidget); //创建布局
 75         pCheckBox = new QCheckBox(pWidget);
 76         //根据objectName ,去拆解所属的tableWidget 、行、列
 77         pCheckBox->setObjectName(QString("%1_%2_%3_Itme").arg(table->objectName()).arg(row).arg(column));
 78         pCheckBox->setChecked(false);
 79         pCheckBox->setFont(table->font());
 80         pCheckBox->setFocusPolicy(Qt::NoFocus);
 81         pCheckBox->setStyle(QStyleFactory::create("fusion"));
 82         pCheckBox->setStyleSheet(QString(".QCheckBox {margin:3px;border:0px;}QCheckBox::indicator {width: %1px; height: %1px; }").arg(50));
 83         hLayout->addWidget(pCheckBox); //添加
 84         hLayout->setMargin(0); //设置边缘距离
 85         hLayout->setAlignment(pCheckBox, Qt::AlignCenter); //居中
 86         hLayout->setSpacing(0);
 87         pWidget->setLayout(hLayout); //设置widget的布局
 88         table->setCellWidget(row,column,pWidget);
 89     }
 90     QList<QCheckBox *> allCheckBoxs =  pWidget->findChildren<QCheckBox *>();
 91     if(allCheckBoxs.size() > 0)
 92         pCheckBox = allCheckBoxs.first();
 93     return pCheckBox;
 94 }
 95 //处理CheckBox
 96 QCheckBox* DlgTableWidget::setCheckBox(QTableWidget*table,int row ,int column,bool checkd)
 97 {
 98     QCheckBox *check = getCheckBox(table,row,column);
 99     if(check != 0) //
100     {
101         check->setChecked(checkd);
102     }
103     QCheckBox::connect(check,&QCheckBox::stateChanged,[=]{
104         QString objectName = check->objectName();
105         QStringList nameList = objectName.split("_");//拆解
106         if(nameList.count() == 4)
107         {
108             QString tableName = nameList.at(0);//表格名称
109             int row = nameList.at(1).toInt();//
110             int column = nameList.at(2).toInt();//
111             bool checked = check->isChecked();//是否被选中
112 
113             //知道了表格、行、列,就可以执行我们所需要的操作了。。。
114             qDebug() << QString("%1表第%2行第%3列是否被选中:%4")
115                             .arg(tableName).arg(row).arg(column).arg(checked?"":"");
116 
117         }
118     });
119     return check;
120 }
121 //响应复选框点击的槽函数
122 void DlgTableWidget::SlotSetChecked(int nState)
123 {
124     QCheckBox *senderObj = qobject_cast<QCheckBox*>(sender());
125         if (senderObj == nullptr)
126         {
127             return;
128         }
129         qDebug() << senderObj->frameGeometry().x() << senderObj->frameGeometry().y() << "-------------------";
130         QModelIndex idx = ui->tableWidget->indexAt(QPoint(senderObj->parentWidget()->frameGeometry().x(), senderObj->parentWidget()->frameGeometry().y()));
131         int row = idx.row();
132         bool enable = senderObj->isChecked();
133 
134         qDebug() << row << enable <<"+++++++++++++++++++++";
135 }

2、QheaderView表头实现复选框

头文件

 1 #ifndef CHECKBOXHEADERVIEW_H
 2 #define CHECKBOXHEADERVIEW_H
 3 
 4 #include <QtGui>
 5 #include <QPainter>
 6 #include <QHeaderView>
 7 #include <QStyleOptionButton>
 8 #include <QStyle>
 9 #include <QCheckBox>
10 
11 /// 复选框表头
12 
13 class CheckBoxHeaderView : public QHeaderView
14 {
15     Q_OBJECT
16 private:
17     int     m_checkColIndex;    //列下标
18     QPoint  m_topLeft;          //勾选框起始坐标
19     QSize   m_checkSize;        //勾选框大小
20     bool    m_isChecked;        //勾选框状态
21 public:
22     CheckBoxHeaderView( int checkColumnIndex, QPoint topLeft, QSize size, Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
23     {
24         m_checkColIndex = checkColumnIndex;
25         m_topLeft = topLeft;
26         m_checkSize = size;
27         m_isChecked = false;
28     }
29 
30     void setCheckState(bool state)
31     {
32         m_isChecked = state;
33     }
34 
35 protected:
36     void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
37     {
38         painter->save();
39         QHeaderView::paintSection(painter, rect, logicalIndex);
40         painter->restore();
41         if (logicalIndex == m_checkColIndex)
42         {
43             QStyleOptionButton option;
44             int width = 10;
45             for (int i=0; i<logicalIndex; ++i)
46             {
47                 width += sectionSize( i );
48             }
49             option.rect = QRect(m_topLeft.x(), m_topLeft.y(), m_checkSize.width(), m_checkSize.height());
50             if (m_isChecked)
51             {
52                 option.state = QStyle::State_On;
53             }
54             else
55             {
56                 option.state = QStyle::State_Off;
57             }
58             QCheckBox *check = new QCheckBox;
59             check->setVisible(false);
60             QString sheet = QString("QCheckBox::indicator {width: %1px;  height: %2px;}").arg(m_checkSize.width()).arg(m_checkSize.height());
61             check->setStyleSheet(sheet);
62             this->style()->drawControl(QStyle::CE_CheckBox, &option, painter, check);
63         }
64     }
65 
66     void mousePressEvent(QMouseEvent *event)
67     {
68         if (visualIndexAt(event->pos().x()) == m_checkColIndex)
69         {
70             m_isChecked = !m_isChecked;
71             this->updateSection(m_checkColIndex);
72             emit checkStatusChange(m_isChecked);
73         }
74         QHeaderView::mousePressEvent(event);
75     }
76 signals:
77     void checkStatusChange(bool);
78 };
79 
80 #endif // CHECKBOXHEADERVIEW_H

使用方法:

InitTable 函数:

 1 void DlgTableWidget::InitTable()
 2 {
 3     ui->tableWidget->horizontalHeader()->setVisible(true);
 4     ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//禁止编辑
 5     ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//选择整行
 6     ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
 7     ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
 8     ui->tableWidget->verticalHeader()->setVisible(false);
 9     ui->tableWidget->setColumnCount(5);
10     ui->tableWidget->setRowCount(0);
11 
12     CheckBoxHeaderView *myHeader = new CheckBoxHeaderView(0, QPoint(50 , 13),QSize(50 , 50 ), Qt::Horizontal, ui->tableWidget);
13     myHeader->setObjectName(QStringLiteral("m_checkHeaderView"));
14 
15     ui->tableWidget->setHorizontalHeader(myHeader);
16     connect(myHeader, &CheckBoxHeaderView::checkStatusChange, this, &DlgTableWidget::SlotCheckBoxStateChange);
17 
18     myHeader->setDefaultAlignment(Qt::AlignLeft | Qt::AlignCenter);
19 
20     ui->tableWidget->setStyleSheet("QTableWidget::indicator {width: 40px;height: 40px;}");//QTableWidget::indicator:unchecked {image: url(:/icon/unchecked.png);}QTableWidget::indicator:checked {image: url(:/icon/checked.png);}");
21 
22     ui->tableWidget->horizontalHeader()->setMinimumHeight(80);
23     ui->tableWidget->horizontalHeader()->setStretchLastSection(true);//最后一列自动充满
24     ui->tableWidget->horizontalHeader()->setVisible(true);
25     ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);//平均分配列宽
26     ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{border:0px solid rgb(218, 222, 226);background-color: rgb(204, 217, 230);font: 11pt '微软雅黑'}");
27 
28     bool b = connect(ui->tableWidget,&QTableWidget::cellChanged,this,&DlgTableWidget::SlotChangeCheckbox);
29     //设置表头
30     QStringList header;
31     header << tr("") << tr("检测对象") << tr("检测项目") << tr("状态描述");
32     ui->tableWidget->setHorizontalHeaderLabels(header);
33     QStringList list ;
34     list << "" << "对象" << "项目" << "描述";// << <<;
35     for (int i = 0; i < 10; i++) {
36         InsertTable(list);
37     }
38 }

表头复选框槽函数:

里面没做实现。大概思路是:如果(不)勾选了表头复选框,遍历表格,做相应操作;如果勾选表格中复选框,对表头做相应操作,要注意表头的三态。

void DlgTableWidget::SlotCheckBoxStateChange(bool bState)
{
    int i = 1;

}

 

posted @ 2022-11-11 17:30  阳光下的小土豆  阅读(2962)  评论(0编辑  收藏  举报