自学内容网 自学内容网

QTableWidget表头添加全选框

前言

QTableWidget表头不能直接设置复选框,setCheckState不适用,所以直接使用设置图片的方法最方便快捷,准备两个图片,分别为选中状态未选中状态

1.设置复选框列

设置第一列为复选框列,其他列正常显示内容:

for (int j = 0; j < table_head.size(); ++j)
{
if (j == 0)//全选列 
{
        //不直接设置setCellWidget为QCheckBox,使用布局再添加可使复选框居中
QCheckBox *pCheckBox = new QCheckBox();
pCheckBox->setCheckState(Qt::Unchecked);
QWidget *pWgt = new QWidget;
QVBoxLayout *pLayout = new QVBoxLayout;
pLayout->addWidget(pCheckBox);
pWgt->setLayout(pLayout);
        //设置margin,使复选框列窄一点,默认宽度比较大
pCheckBox->setContentsMargins(0, 0, 0, 0);
pLayout->setMargin(2);
tableWidget->setCellWidget(i, j, pWgt);
}
else {
QTableWidgetItem * pItem;
pItem = new QTableWidgetItem;
pItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
pItem->setTextAlignment(Qt::AlignCenter);
tableWidget->setItem(i, j, pItem);
        tableWidget->setText("abc");
}
}

 2.设置表头图片与样式

直接添加Icon,默认会紧贴表格的左侧,并不居中,非常不好看。

所以使用setStyleSheet设置表头样式,如果使用QHeaderView::section是默认对所以表头设置样式,所以在设置样式时使用QHeaderView::section:first,只设置第一列左边距为6,这是我测试出比较合适的宽度。

设置表头全选框图片时,仍然可以拖动列宽,我不希望第一列可以拖动,因为没有意义,所以设置horizontalHeaderQHeaderView::Fixed模式,不允许拖动列宽。

这样就是比较美观的表格了。

//添加全选
tableWidget->horizontalHeaderItem(0)->setIcon(QIcon(":/Resources/res/icon/uncheck.png"));
//表头第一列图片左边距设置为6
tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section:first { padding-left: 6px; }");
tableWidget->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
//设置第一列不能拖动,为固定宽度
tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);

3.全选响应事件

对表头进行点击事件响应,使用sectionClicked信号。

connect(tableWidget->horizontalHeader(), &QHeaderView::sectionClicked, this, & Test::slot_onHeaderClicked);
void Test::slot_onHeaderClicked(int logicalIndex)
{
if (logicalIndex != 0)
{
return;
}
QString strText = tableWidget->horizontalHeaderItem(0)->text();
    //m_bChecked用来对表头全选图片进行设置
if (!m_bChecked)
{
m_bChecked = true;
tableWidget->horizontalHeaderItem(0)->setIcon(QIcon(":/Resources/res/icon/checked.png"));
}
else
{
m_bChecked = false;
tableWidget->horizontalHeaderItem(0)->setIcon(QIcon(":/Resources/res/icon/uncheck.png"));
}
//全选
int nRow = tableWidget->rowCount();
for (int i = 0; i < nRow; i++)
{
QCheckBox *pCheckBox = getCheckBox(i);//获取第一列中的复选框
if (pCheckBox == nullptr)
{
continue;
}
if (m_bChecked)
{
pCheckBox->setChecked(true);
}
else
{
pCheckBox->setChecked(false);
}
}

}

4.第一列选择框,勾选响应事件

需求:

(1)单选时,当前列多选框勾选

(2)鼠标左键按下时拖拽,可选多行

设置表格为多选模式:

tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);

实现的信号:

connect(tableWidget, &QTableWidget::itemSelectionChanged, this, &Test::slot_checkStates);

实现:

void Test::slot_checkStates()
{
int curiRow = tableWidget->currentRow();
//获取勾选框
QCheckBox *pCheckBox = getCellCheckBox(curiRow);
if (pCheckBox == nullptr)
{
return;
}
if (pCheckBox->isChecked())
pCheckBox->setChecked(false);
else
pCheckBox->setChecked(false);
tableWidget->horizontalHeaderItem(0)->setIcon(QIcon(":/Resources/res/icon//uncheck.png"));
m_bChecked = false;
QList<QTableWidgetItem*> lstSelectedItems = tableWidget->selectedItems();
QList<int> lstSelectedRow;
for (int i = 0; i < lstSelectedItems.size(); i++)
{
if (lstSelectedItems.at(i) == nullptr)
{
continue;
}
int nRow = lstSelectedItems.at(i)->row();
if (!lstSelectedRow.contains(nRow))
{
lstSelectedRow << nRow;
}
}
for (int m = 0; m < tableWidget->rowCount(); m++)
{
QCheckBox *pTmpCheckBox = getCellCheckBox(m);
if (pTmpCheckBox == nullptr)
{
continue;
}
//设置选中,异或,只符合一个条件才行
if ((lstSelectedRow.size() > 0 && lstSelectedRow.contains(m)) ^ (lstSelectedRow.size() == 0 && m == curiRow))
{
pTmpCheckBox->setChecked(true);
continue;
}
pTmpCheckBox->setChecked(false);
}
}


原文地址:https://blog.csdn.net/qq_41567921/article/details/140214933

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!