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; }