最近項目有需求,做一個類似這樣的子產品界面,于是第一時間想着用的是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