Qt开发笔记之QTableWidget的使用

Qt开发笔记之QTableWidget的使用

  • 前言
  • 需求
  • 数据准备
  • tablewidget用法
  • STL map的使用
  • 自定义控件的加入
  • 后记

前言

QT是我唯一会用的图形库。虽然C++在图形编程方面不算主流,但是Qt在界面之外还提供了很多优秀的支持。可以说Qt更像是平台而不是一个图形库,比如它提供了自己的模板代替STL,有自己的一套多线程API和网络API,还有信号与槽机制。总的来说,Qt对于C++开发人员来说还是一个十分给力的工具。
这个系列相当于我个人开发的日记,可能质量不会很高,很多细节也不会讲,如果有兴趣了解的朋友可以留言,如果只是想学习技术请移步本文链接中其他好文章。

需求

我们今天要使用的是QTableWidget这个控件,首先介绍一下我们要实现的功能。在这里插入图片描述
我们有这样一个系统,左侧是一个树形控件,右侧是一个QTableWidget控件。我们要做的是,在左侧点击某一类控件时,能在右边的QTableWidget上显示所有该类的设备。
我们的表头有四个:名称,上级名称,品牌和操作。前三项可以通过数据库查询到,而后面一项比较特殊,是一个信息按钮和一个删除按钮。
接下来看如何实现我们的需求。

数据准备

我们首先准备需要显示数据,数据从数据库中获取。关于数据库的操作我们可以看这篇博客:Qt学习之路八——利用qt对数据库进行操作。我们远程连接centos上的mysql数据库,代码如下:

1
2
3
4
5
6
7
8
9
10
11
//打开数据库
    QSqlDatabase data_base = QSqlDatabase::addDatabase("QMYSQL");
    data_base.setHostName("192.168.101.162");
    data_base.setPort(3306);
    data_base.setDatabaseName("mydb");
    data_base.setUserName("root");
    data_base.setPassword("password");
    if (!data_base.open()) {
        QMessageBox::warning(this, "错误", data_base.lastError().text());
        return;
    }

如果没有报错我们就执行标准sql语句查数据库了:

1
2
3
4
5
6
7
8
9
10
11
12
    QString sql;
    if (cat == 0)//输入类别为0我们查所有数据,否则根据cat查特定class的数据
        sql = QString("select * from device");
    else
        sql = QString("select * from device where class = '%1'").arg(QString::number(cat));
    QSqlQuery query;
    query.exec(sql);
    while (query.next())
    {
        QString name = query.value(1).toString();
        //...
    }

在while循环中,我们实际上是一行一行地访问数据表中地内容,接下来我们看如何把这些数据显示到我们的界面上面。

tablewidget用法

关于tablewidget的用法,可以看看这篇博客:Qt QTableWidget用法总结。
我们固定显示15行,配合上交错色使界面显得更为美观,当多出15行时我们就增加行数(这个增加行数是不是必要的,我没有测试);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    int rows = 0;
    ui.tableWidget->clearContents();
    ui.tableWidget->setRowCount(15);
    ui.tableWidget->setFocusPolicy(Qt::NoFocus);
    int cat = show_cat;
    while (query.next())
    {
        if(rows>=15)
            ui.tableWidget->setRowCount(rows+1);
        QString name = query.value(1).toString();
        QString parent = get_parent(query.value(4).toInt());
        QString brand = query.value(2).toString();
        QString inf = query.value(3).toString();
        QTableWidgetItem *item_name = new QTableWidgetItem(name);
        set_itemstyle(item_name);
        QTableWidgetItem* item_parent = new QTableWidgetItem(parent);
        set_itemstyle(item_parent);
        QTableWidgetItem* item_brand = new QTableWidgetItem(brand);
        set_itemstyle(item_brand);
        ui.tableWidget->setItem(rows, 0, item_name);
        ui.tableWidget->setItem(rows, 1, item_parent);
        ui.tableWidget->setItem(rows, 2, item_brand);
        rows++;
    }

这样每次得到请求都去访问数据库,可能开销会大些。但是可以保证显示上表现的正常。在这里插入图片描述
我们这里的parent是一个数字,例如11代表了视频设备下的摄像机。我们通过map建立一个转换。

STL map的使用

map是C++ STL中的一个关联容器,也就是关键字——值对的集合,在这篇博客中我们不过多将它的原理方法,只看下怎么用并编写一个函数建立int到QString的map关系。

  • map的创建和搜索:
1
2
3
    map<string, string> full_name;//初始化
    full_name["LeBron"] = "James";;
    cout << full_name.find("LeBron")->second << endl;

如果我们要对关联容器进行值初始化就这样写:

1
2
3
4
5
6
    map<string, string> full_name = {
     {"Stephen","Curry"},
     {"James","Harden"},
     {"LeBron","James"}
    };
    cout << full_name.find("James")->second << endl;

那么我们就来建立我们的map:

1
2
3
4
5
6
7
8
9
std::map<int, QString> cmap;
cmap = {{11,QString::fromLocal8Bit("摄像机")},{12,QString::fromLocal8Bit("视频平台")}};

//根据int返回名字:
QString VideoSuveillance::get_parent(int cat)
{
    QString ret = cmap.find(cat)->second;
    return ret;
}

在这里插入图片描述
界面已经开始有模有样了吧。

自定义控件的加入

在列表的第四项是一个自定义控件,包含一个信息按钮和一个删除按钮。我们来看一看如何实现。
首先我们用Qt Creator画一个界面,并编译它在这里插入图片描述
然后我们写一下这个类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once
#include "ui_ITEM.h"

class Item
    : public QWidget
{
    Q_OBJECT

public:
    Item(QWidget* parent = Q_NULLPTR);

private:
    Ui::Item ui;
};
1
2
3
4
5
6
7
#include "ITEM.h"

Item::Item(QWidget* parent)
    : QWidget(parent)
{
    ui.setupUi(this);
}

之后就可以像widget一样向table中添加了,代码如下:

1
2
        Item* it = new Item();
        ui.tableWidget->setCellWidget(rows, 3,it);

setCellWidget函数是专门向table中添加widget类的,我们来看看效果:在这里插入图片描述
是不是还可以呢?

后记

今天基本完成了界面二的开发,下周把界面三搞完就基本收工啦。