Qt基础控件学习04 QTableWidget(详解)

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

而且这个模块需要有单击双击的动作。

Qt基础控件学习04 QTableWidget(详解)_第1张图片

开发的过程,不可避免的就是查一下文档,或者看看别人怎么写的。于是就顺便学一下QTablewidget。先上点基础的有用的

一、设置表单样式

  table_widget->setColumnCount(4); //设置列数

ui->tableWidget->setColumnWidth(0,20);//单独设置某一列的宽度

  table_widget->horizontalHeader()->setDefaultSectionSize(150); 
  table_widget->horizontalHeader()->setClickable(false); //设置表头不可点击(默认点击后进行排序)

 

  //设置表头内容
  QStringList header;
  header<   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

 

你可能感兴趣的:(QT控件)