最近项目有需求,做一个类似这样的模块界面,于是第一时间想着用的是QTablewidget来实现,原因是赋值和取值都方便一些,
而且这个模块需要有单击双击的动作。

开发的过程,不可避免的就是查一下文档,或者看看别人怎么写的。于是就顺便学一下QTablewidget。先上点基础的有用的
一、设置表单样式
table_widget->setColumnCount(4); //设置列数
ui->tableWidget->setColumnWidth(0,20);//单独设置某一列的宽度
table_widget->horizontalHeader()->setDefaultSectionSize(150);
table_widget->horizontalHeader()->setClickable(false); //设置表头不可点击(默认点击后进行排序)
//设置表头内容
QStringList header;
header<<tr("name")<<tr("last modify time")<<tr("type")<<tr("size");
table_widget->setHorizontalHeaderLabels(header);
//设置表头字体加粗
QFont font = this->horizontalHeader()->font();
font.setBold(true);
table_widget->horizontalHeader()->setFont(font);
table_widget->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
table_widget->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
table_widget->verticalHeader()->setDefaultSectionSize(10); //设置行高
table_widget->setFrameShape(QFrame::NoFrame); //设置无边框
table_widget->setShowGrid(false); //设置不显示格子线
table_widget->verticalHeader()->setVisible(false); //设置垂直头不可见
table_widget->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
table_widget->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
table_widget->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
table_widget->horizontalHeader()->resizeSection(0,150); //设置表头第一列的宽度为150
table_widget->horizontalHeader()->setFixedHeight(25); //设置表头的高度
table_widget->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
table_widget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}"); //设置表头背景色
//设置水平、垂直滚动条样式
table_widget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
"QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
"QScrollBar::handle:hover{background:gray;}"
"QScrollBar::sub-line{background:transparent;}"
"QScrollBar::add-line{background:transparent;}");
table_widget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}"
"QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
"QScrollBar::handle:hover{background:gray;}"
"QScrollBar::sub-line{background:transparent;}"
"QScrollBar::add-line{background:transparent;}");
查看了别人的博客。接下来自己就要动手了。先看看效果在依次解析一下,里面遇到一些过程中的问题(干货):
一个是用QTableWidget做的,一个是QListWidget做的。先说说QTableWidget
1.首先去掉表格头,和网格
ui->tableWidget->horizontalHeader()->setHidden(true);
ui->tableWidget->setShowGrid(false); //设置不显示格子线
2.表格中第二列加入一个Qlabel。
QLabel *label = new QLabel();
label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
label->setText(QString::number(5-i));
label->setStyleSheet("color:rgb(255, 255, 255);"
"border-radius:4px;"
"background-color:rgb(85, 0, 255);"
"font: 9pt;");
ui->tableWidget->setIndexWidget(index,label);
但是光这样是不行的,tablewidget的单元格默认把label控件撑满
为了解决这个问题,我当时也是查了不少博客,但大多数结果都不是很满意。于是看到有人说用布局的思路。大概思路就是,用一个qwidget来装一个布局,在布局里调整一下控件的margin来达到内部的位置调整,再把qwidget装入单元格,即使他自动撑满也没关系。设置好控件的最大尺寸。label->setMaximumSize(14,14);大功告成。
QWidget *widget = new QWidget;
QHBoxLayout *hLayout;
hLayout = new QHBoxLayout();
hLayout->addWidget(label);
hLayout->setMargin(0);
hLayout->setAlignment(widget, Qt::AlignCenter);
hLayout->setContentsMargins(1, 3, 1, 3);
widget->setLayout(hLayout);
ui->tableWidget->setIndexWidget(index,widget);
2.去掉表格中的虚线,和表格中行的背景色随鼠标移动。
参考了下:大概是在表格中重写一个委托类
QStyledItemDelegate类中一个paint函数。就可以。
StyledDelegate *dele = new StyledDelegate();
ui->tableWidget->setItemDelegate(dele);
class StyledDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit StyledDelegate(QObject *parent = Q_NULLPTR);
~StyledDelegate();
void StyledDelegate::paint(QPainter* painter, const QStyleOptionViewItem & option, const QModelIndex &index) const
{
QStyleOptionViewItem itemOption(option);
if (itemOption.state & QStyle::State_HasFocus)
{
itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
}
//添加鼠标滑过的背景色
if(option.state & QStyle::State_MouseOver){
painter->fillRect(itemOption.rect, QColor(180, 200, 220));
}
QStyledItemDelegate::paint(painter, itemOption, index);
}
};
但这样也仅仅只能单个单元格。后面想了一下,tablewidget类设计的操作的单元应该是单元格,应该不会封装行或者列之类的。如果真要达到,背景行跟随的话,思路就是取到行数,然后for()循环一个个单元刷掉。思路可以参考一下:https://blog.csdn.net/m0_37907070/article/details/78642599
我这里就不再多写。因为后面想了一下qlistwidget实现这个功能非常简单
先上一下tablewidget的完整源码:
ui->tableWidget->horizontalHeader()->setHidden(true);
ui->tableWidget->verticalHeader()->setHidden(true);
ui->tableWidget->setColumnCount(4);
ui->tableWidget->setRowCount(10);
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
//ui->tableWidget->setFrameShape(QFrame::NoFrame); //设置无边框
ui->tableWidget->setShowGrid(false); //设置不显示格子线
//ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
//ui->tableWidget->setStyleSheet("selection-background-color:rgb(255,209,128,0)");
ui->tableWidget->setStyleSheet("QTableWidget::item:selected{background-color:rgb(0,0,0,0);color:rgb(0,0,0)}");
ui->tableWidget->setColumnWidth(0,20);
ui->tableWidget->setColumnWidth(1,20);
ui->tableWidget->setColumnWidth(2,80);
ui->tableWidget->setColumnWidth(3,80);
ui->tableWidget->setMouseTracking(true);
StyledDelegate *dele = new StyledDelegate();
ui->tableWidget->setItemDelegate(dele);
QAbstractItemModel *model = ui->tableWidget->model();
for(int i = 0; i<10; i++)
{
ui->tableWidget->setRowHeight(i,22);
QModelIndex index = model->index(i,1);
QLabel *label = new QLabel();
label->setMaximumSize(14,14);
label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
if(i<5)
{
ui->tableWidget->setItem(i,0,new QTableWidgetItem(QString("S")));
label->setText(QString::number(5-i));
label->setStyleSheet("color:rgb(255, 255, 255);"
"border-radius:4px;"
"background-color:rgb(85, 0, 255);"
"font: 9pt;"
"");
}
else
{
ui->tableWidget->setItem(i,0,new QTableWidgetItem(QString("B")));
label->setText(QString::number(i-4));
label->setStyleSheet("color:rgb(255, 255, 255);"
"border-radius:4px;"
"background-color:rgb(204, 0, 0);"
"font: 9pt;");
}
QWidget *widget = new QWidget;
QHBoxLayout *hLayout;
hLayout = new QHBoxLayout();
hLayout->addWidget(label);
hLayout->setMargin(0);
hLayout->setAlignment(widget, Qt::AlignCenter);
hLayout->setContentsMargins(1, 3, 1, 3);
widget->setLayout(hLayout);
ui->tableWidget->setIndexWidget(index,widget);
QTableWidgetItem * item3 = new QTableWidgetItem(QString("0.001"));
QTableWidgetItem * item4 = new QTableWidgetItem(QString("1000"));
item3->setTextAlignment(Qt::AlignRight| Qt::AlignHCenter);
item4->setTextAlignment(Qt::AlignRight| Qt::AlignHCenter);
ui->tableWidget->setItem(i,2,item3);
ui->tableWidget->setItem(i,3,item4);
}
然后是qlistwidget的
for(int i = 0; i<10; i++)
{
QListWidgetItem *item=new QListWidgetItem;
item->setSizeHint(QSize(0,22));
ui->listWidget->addItem(item);
QLabel *label1 = new QLabel();
QLabel *label2 = new QLabel();
QLabel *label3 = new QLabel("0.001");
QLabel *label4 = new QLabel("100000");
label1->setMaximumSize(16,16);
label2->setMaximumSize(14,14);
label1->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
label2->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
label3->setAlignment(Qt::AlignHCenter | Qt::AlignRight);
label4->setAlignment(Qt::AlignHCenter | Qt::AlignRight);
if(i<5)
{
label1->setText("S");
label2->setText(QString::number(5-i));
label2->setStyleSheet("color:rgb(255, 255, 255);"
"border-radius:4px;"
"background-color:rgb(85, 0, 255);"
"font: 9pt;");
}
else
{
label1->setText("B");
label2->setText(QString::number(i-4));
label2->setStyleSheet("color:rgb(255, 255, 255);"
"border-radius:4px;"
"background-color:rgb(204, 0, 0);"
"font: 9pt;");
}
QWidget *widget = new QWidget;
QHBoxLayout *hLayout;
hLayout = new QHBoxLayout();
hLayout->addWidget(label1);
hLayout->addWidget(label2);
hLayout->addWidget(label3);
hLayout->addWidget(label4);
hLayout->setMargin(0);
hLayout->setAlignment(widget, Qt::AlignCenter);
hLayout->setContentsMargins(1, 3, 1, 3);
widget->setLayout(hLayout);
ui->listWidget->setItemWidget(item,widget);
}
//样式
QListWidget::item:selected:active { background:rgb(0, 0, 223,0);}
QListWidget::item:selected:!active { background:rgb(0, 0, 223,0);}
是不是感觉Qlistwidget的很简单?
参考一下博客:
https://blog.csdn.net/m0_37907070/article/details/78642599
http://blog.sina.com.cn/s/blog_a6fb6cc90101i8it.html
https://www.cnblogs.com/zhoug2020/p/3789076.html