Qt writing visual large-screen electronic Kanban system 30-module 8 material management

I. Introduction

The material management module includes sub-modules of inventory ratio and main parts inventory status. The inventory ratio is displayed by a custom control circular progress bar. There are a variety of inventories in total, and different interfaces are displayed according to the names in the database. When the inventory is not enough At the time, the color of the corresponding annular progress bar is displayed in red; the main parts inventory data is displayed in a table, and there is an early warning progress bar at the end, and the fields include serial number, product name, specification, material, size, target inventory, current inventory, and inventory percentage;

Submodule table name corresponding table:

submodule title submodule table name
Inventory ratio t_8_1_key_invt
Major Parts Inventory t_8_2_invt_table

1 Inventory ratio

Table name: t_8_1_key_invt

field name Chinese name Types of length illustrate
internal_id serial number INTEGER 11 Primary key auto increment
name name VARCHAR 255
upper_bound upper limit INTEGER 11
current in stock INTEGER 11

Default data:

internal_id name upper_bound current
1 Tool A1 200 110
2 Thimble B 100 70
3 wire cutting wire C 100 300
4 Resin D 100 10

2 Main parts inventory

Table name: t_8_2_invt_table

field name Chinese name Types of length illustrate
internal_id serial number INTEGER 11 Primary key auto increment
invt_no serial number VARCHAR 255
name Product name VARCHAR 255
spec Specification VARCHAR 255
mat Material VARCHAR 255
size size VARCHAR 255
target target inventory INTEGER 11
current Current inventory INTEGER 11

Default data:

internal_id invt_no name spec mat size target current
1 SSDDS1 Product name 1 Specification 1 Material 1 345420 200 90
2 SSDDS2 Product name 2 Specification 2 Material 2 345420 100 120
3 SSDDS3 Product name 3 Specification 3 Material 3 345420 100 67
4 SSDDS4 Product name 4 Specification 4 Material 4 345420 100 88
5 SSDDS5 Product name 5 Specification 5 Material 5 345420 100 45
6 SSDDS6 Product name 6 Specification 6 Material 6 345420 100 87
7 SSDDS7 Product name 7 Specification 7 Material 7 345420 100 9
8 SSDDS8 Product name 8 Specification 8 Material 8 345420 100 44
9 SSDDS9 Product name 9 Specification 9 Material 9 345420 100 100

2. Features

  1. The layered design is adopted, and the whole is divided into three levels of interfaces. The first level interface is the overall layout, the second level interface is a single function module, and the third level interface is a single control.
  2. Sub-controls include pie chart, doughnut chart, curve chart, column chart, column group chart, horizontal column chart, horizontal column group chart, pass rate control, percentage control, progress control, equipment status panel, table data, map control , video controls, etc.
  3. The secondary interface can be freely dragged and suspended, and supports minimizing and hiding, maximizing and closing, and responding to double-clicks to customize the title bar.
  4. 数据源支持模拟数据(默认)、数据库采集、串口通信(需定制)、网络通信(需定制)、网络请求等,可自由设定每个子界面的采集间隔即数据刷新频率。
  5. 采用纯QWidget编写,亲测Qt4.6到Qt6.2任意版本,理论上支持后续其他Qt版本。
  6. 超强跨平台,亲测windows、linux、mac、国产uos、国产银河麒麟kylin等系统,效果完美,同时还支持嵌入式linux比如树莓派、香橙派、全志、imx6等。
  7. 同时集成了自定义控件、qchart饼图、echart地图等功能。
  8. 内置多套配色风格样式(紫色、蓝色、深蓝、黑色),默认紫色,自适应任意分辨率。
  9. 可设置系统标题、目标分辨率、布局方案,启动立即应用。
  10. 可设置主背景颜色、面板颜色、十字线游标颜色等各种颜色。
  11. 可设置多条曲线不同颜色,没有设置颜色的情况下内置多套精美颜色随机应用。
  12. 可设置标题栏背景颜色、文字颜色。
  13. 可设置曲线图表背景颜色、文字颜色、网格颜色。
  14. 可设置正常颜色、警戒颜色、报警颜色、禁用颜色、百分比进度颜色。
  15. 可分别设置各种字体大小,比如全局字体、软件名称、标题栏、子标题栏、加粗标签等。
  16. 可设置标题栏高度、表头高度、行高度。
  17. 曲线支持游标、定位线、悬停高亮数据点、悬停显示值。
  18. 柱状图支持顶部(可设置顶端、上部、中间、底部)显示数据,全部自适应计算位置。
  19. 支持平滑曲线,内置多种平滑曲线算法,还支持面积图平滑。
  20. 面积图填充颜色可选多种规则比如单色透明度填充、透明度渐变填充等。
  21. 数据库支持sqlite、mysql、postgresql、oracle、国产人大金仓等数据库。
  22. 主界面直接鼠标右键切换布局、配色方案、关闭开启某个二级窗体。
  23. 自动记忆所有子窗口的大小和位置,下次启动立即应用。
  24. 动态加载布局方案菜单,可以动态新建布局、恢复布局、保存布局、另存布局等,用户可以制造任意布局。
  25. 二级窗体,双击从主窗体分离出来浮动,可以自由调整大小。再次双击标题栏最大化,再次双击还原。
  26. 子模块也可以全屏显示作为一个大屏,这样就可以一个大屏拓展出多个子大屏,放大查看子模块的数据详情,适用多屏展示。
  27. 每个模块都可以自定义采集速度,如果是数据库采集会自动排队处理,后期还可以拓展每个子模块都独立的数据库采集。
  28. 提供系统设置模块进行整体的配置参数设置,效果立即应用。
  29. 提供精美炫酷的大屏地图模块,包括静态图片、闪烁效果、迁徙效果、世界地图、区域地图等,可指定点的经纬度坐标,识别单击响应,可以做地图跳转等,每个点都可以不同的颜色和提示信息。
  30. 除了提供大屏系统外,还将每个模块都做了独立的模块示例界面,每个模块都可以独立学习使用,里面用到的控件也单独做了控件示例界面,方便学习每个控件如何使用。
  31. 非常详细的开发和使用手册,其中包括数据库说明、模块对照图、控件对照图、项目结构、代码说明(精确到每个类)、演示demo、使用方法等。

三、体验地址

  1. 体验地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取码:01jf 文件名:bin_bigscreen.zip。
  2. 国内站点:https://gitee.com/feiyangqingyun
  3. 国际站点:https://github.com/feiyangqingyun
  4. 个人主页:https://blog.csdn.net/feiyangqingyun
  5. 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
  6. 在线文档:https://feiyangqingyun.gitee.io/qwidgetdemo/bigscreen/

四、效果图

在这里插入图片描述

五、核心代码

#include "frmmodule8.h"
#include "ui_frmmodule8.h"
#include "quihelper.h"
#include "progressthree.h"

frmModule8::frmModule8(QWidget *parent) : QWidget(parent), ui(new Ui::frmModule8)
{
    ui->setupUi(this);
    this->initForm();
    this->initRing();
    this->initTable();
}

frmModule8::~frmModule8()
{
    delete ui;
}

void frmModule8::initForm()
{
    //设置对应的属性应用特定样式
    ui->labTitle1->setProperty("flag", "title");
    ui->labTitle2->setProperty("flag", "title");
    ui->labTitle3->setProperty("flag", "title");
    ui->labTitle4->setProperty("flag", "title");
    ui->labTitle5->setProperty("flag", "title");

    ui->widgetSub1->setProperty("flag", "sub");
    ui->widgetSub2->setProperty("flag", "sub");
    ui->widgetSub3->setProperty("flag", "sub");
    ui->widgetSub4->setProperty("flag", "sub");
    ui->widgetSub5->setProperty("flag", "sub");

    ui->widgetLab1->setProperty("flag", "lab");
    ui->widgetLab2->setProperty("flag", "lab");
    ui->widgetLab3->setProperty("flag", "lab");
    ui->widgetLab4->setProperty("flag", "lab");

    //定时器模拟数据
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(loadRing()));
    connect(timer, SIGNAL(timeout()), this, SLOT(loadTable()));

    //绑定信号槽处理接收的数据+发送执查询语句
    connect(DbData::DbLocal, SIGNAL(receiveData(QString, QStringList, int)),
            this, SLOT(receiveData(QString, QStringList, int)));
    connect(DbData::DbHttp, SIGNAL(receiveData(QString, QStringList, int)),
            this, SLOT(receiveData(QString, QStringList, int)));
}

void frmModule8::receiveData(const QString &tag, const QStringList &data, int mesc)
{
    int count = data.count();
    if (tag == "t_8_1_key_invt") {
        if (count % 3 == 0 && count == 12) {
            QString name1, name2, name3, name4;
            int value1, value2, value3, value4, valueAll1, valueAll2, valueAll3, valueAll4;
            value1 = data.at(2).toInt();
            valueAll1 = data.at(1).toInt();
            name1 = data.at(0);
            value2 = data.at(5).toInt();
            valueAll2 = data.at(4).toInt();
            name2 = data.at(3);
            value3 = data.at(8).toInt();
            valueAll3 = data.at(7).toInt();
            name3 = data.at(6);
            value4 = data.at(11).toInt();
            valueAll4 = data.at(10).toInt();
            name4 = data.at(9);

            loadName(name1, name2, name3, name4);
            loadRing(value1, value2, value3, value4, valueAll1, valueAll2, valueAll3, valueAll4);
        }
    } else if (tag == "t_8_2_invt_table") {
        if (count % 8 == 0) {
            lstringl values;
            ui->tableWidget->setRowCount(count / 8);
            for (int i = 0; i < count; i = i + 8) {
                QStringList value;
                value << data.at(i);
                value << data.at(i + 1);
                value << data.at(i + 2);
                value << data.at(i + 3);
                value << data.at(i + 4);
                value << data.at(i + 5);
                value << data.at(i + 6);
                value << data.at(i + 7);

                double all = data.at(i + 6).toDouble();
                double current = data.at(i + 7).toDouble();
                double percent = current / all;
                percent = percent * 100;
                //转成整数,去掉小数位
                int p = percent;
                value << QString("%1%").arg(p);

                //大于100则全部为绿色
                if (p > 100) {
                    value << QString("%1|0|%2").arg(100).arg(0);
                } else {
                    value << QString("%1|0|%2").arg(p).arg(100 - p);
                }

                values << value;
            }

            loadTable(values);
        }
    }
}

void frmModule8::initRing()
{
    ui->progressRing1->setRingWidth(25);
    ui->progressRing1->setRingPadding(5);
    ui->progressRing1->setClockWise(false);
    ui->progressRing1->setShowPercent(true);
    ui->progressRing1->setAlarmMode(2);

    ui->progressRing2->setRingWidth(25);
    ui->progressRing2->setRingPadding(5);
    ui->progressRing2->setClockWise(false);
    ui->progressRing2->setShowPercent(true);
    ui->progressRing2->setAlarmMode(2);

    ui->progressRing3->setRingWidth(25);
    ui->progressRing3->setRingPadding(5);
    ui->progressRing3->setClockWise(false);
    ui->progressRing3->setShowPercent(true);
    ui->progressRing3->setAlarmMode(2);

    ui->progressRing4->setRingWidth(25);
    ui->progressRing4->setRingPadding(5);
    ui->progressRing4->setClockWise(false);
    ui->progressRing4->setShowPercent(true);
    ui->progressRing4->setAlarmMode(2);
}

void frmModule8::loadRing()
{
    QString tableName = "t_8_1_key_invt";
    QString columnName = "name,upper_bound,current";

    if (AppConfig::WorkMode == "timer") {
        int max = 150;
        int value1 = QUIHelper::getRandValue(0, max);
        int value2 = QUIHelper::getRandValue(0, max);
        int value3 = QUIHelper::getRandValue(0, max);
        int value4 = QUIHelper::getRandValue(0, max);
        loadRing(value1, value2, value3, value4, max, max, max, max);
    } else if (AppConfig::WorkMode == "db") {        
        DbData::DbLocal->select(tableName, columnName, true);
    } else if (AppConfig::WorkMode == "http") {        
        DbData::DbHttp->select(tableName, columnName, true);
    }
}

void frmModule8::loadName(const QString &name1, const QString &name2, const QString &name3, const QString &name4)
{
    ui->labTitle1->setText(name1);
    ui->labTitle2->setText(name2);
    ui->labTitle3->setText(name3);
    ui->labTitle4->setText(name4);
}

void frmModule8::loadRing(int value1, int value2, int value3, int value4,
                          int valueAll1, int valueAll2, int valueAll3, int valueAll4)
{
    double percent1 = (double)value1 / valueAll1;
    double percent2 = (double)value2 / valueAll2;
    double percent3 = (double)value3 / valueAll3;
    double percent4 = (double)value4 / valueAll4;

    percent1 = percent1 * 100;
    percent2 = percent2 * 100;
    percent3 = percent3 * 100;
    percent4 = percent4 * 100;

    if (percent1 > 100) {
        ui->progressRing1->setValue(percent1);
        ui->progressRing1->setText(QString("%1%").arg(percent1));
    } else {
        ui->progressRing1->setValue(percent1);
        ui->progressRing1->setText("");
    }

    if (percent2 > 100) {
        ui->progressRing2->setValue(percent2);
        ui->progressRing2->setText(QString("%1%").arg(percent2));
    } else {
        ui->progressRing2->setValue(percent2);
        ui->progressRing2->setText("");
    }

    if (percent3 > 100) {
        ui->progressRing3->setValue(percent3);
        ui->progressRing3->setText(QString("%1%").arg(percent3));
    } else {
        ui->progressRing3->setValue(percent3);
        ui->progressRing3->setText("");
    }

    if (percent4 > 100) {
        ui->progressRing4->setValue(percent4);
        ui->progressRing4->setText(QString("%1%").arg(percent4));
    } else {
        ui->progressRing4->setValue(percent4);
        ui->progressRing4->setText("");
    }

    ui->labValue1->setText(QString("库存: %1").arg(value1));
    ui->labValue2->setText(QString("库存: %1").arg(value2));
    ui->labValue3->setText(QString("库存: %1").arg(value3));
    ui->labValue4->setText(QString("库存: %1").arg(value4));

    ui->labMax1->setText(QString("上限: %1").arg(valueAll1));
    ui->labMax2->setText(QString("上限: %1").arg(valueAll2));
    ui->labMax3->setText(QString("上限: %1").arg(valueAll3));
    ui->labMax4->setText(QString("上限: %1").arg(valueAll4));
}

void frmModule8::initTable()
{
    QStringList headText;
    headText << "序号" << "编号" << "品名" << "规格" << "材料" << "尺寸" << "目标库存" << "当前库存" << "库存百分比" << "预警";

    int columnCount = headText.count();
    ui->tableWidget->setColumnCount(columnCount);
    ui->tableWidget->setHorizontalHeaderLabels(headText);
    ui->tableWidget->horizontalHeader()->setMinimumHeight(AppConfig::HeadHeight);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(AppConfig::RowHeight);

    QList<int> widths;
    widths << 50 << 80 << 80 << 80 << 80 << 100 << 80 << 80 << 80 << 80;
    for (int i = 0; i < columnCount; i++) {
        ui->tableWidget->setColumnWidth(i, widths.at(i));
    }

    ui->tableWidget->setFocusPolicy(Qt::NoFocus);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    //ui->tableWidget->setAlternatingRowColors(true);
    ui->tableWidget->verticalHeader()->setVisible(false);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->horizontalHeader()->setHighlightSections(false);
}

void frmModule8::loadTable()
{
    QString tableName = "t_8_2_invt_table";
    QString columnName = "internal_id,invt_no,name,spec,mat,size,target,current";

    if (AppConfig::WorkMode == "timer") {
        lstringl values;
        int rowCount = 13;
        ui->tableWidget->setRowCount(rowCount);
        for (int i = 0; i < rowCount; i++) {
            QStringList value;
            value << QString::number(i + 1);
            value << QString("SSDDS%1").arg(i + 1);
            value << QString("材料%1").arg(i + 1);
            value << QString("规格%1").arg(i + 1);
            value << QString("材料%1").arg(i + 1);
            value << QString("32*54*%1").arg(i + 1);
            value << QString("100");

            double current = QUIHelper::getRandValue(50, 80);
            value << QString("%1").arg(current);
            value << QString("%1%").arg(current);
            value << QString("%1|0|%2").arg(current).arg(100 - current);
            values << value;
        }

        loadTable(values);
    } else if (AppConfig::WorkMode == "db") {        
        DbData::DbLocal->select(tableName, columnName, true);
    } else if (AppConfig::WorkMode == "http") {
        DbData::DbHttp->select(tableName, columnName, true);
    }
}

void frmModule8::loadTable(const lstringl &values)
{
    int rowCount = values.count();
    for (int i = 0; i < rowCount; i++) {
        QStringList value = values.at(i);
        int columnCount = value.count();
        for (int j = 0; j < columnCount; j++) {
            //末尾数据为进度条
            if (j == columnCount - 1) {
                QString data = value.at(j);
                QStringList list = data.split("|");
                if (list.count() != 3) {
                    continue;
                }

                //自定义多态进度条
                ProgressThree *progress = new ProgressThree;
                progress->setValue1(list.at(0).toInt());
                progress->setValue2(list.at(1).toInt());
                progress->setValue3(list.at(2).toInt());
                progress->setFixedHeight(15);
                progress->setShowValue(true);
                progress->setShowPercent(true);
                progress->setRadius(7);

                //增加widget+布局巧妙实现居中
                QWidget *widget = new QWidget;
                QHBoxLayout *layout = new QHBoxLayout;
                layout->setSpacing(0);
                layout->setContentsMargins(3, 3, 3, 3);
                layout->addWidget(progress);
                widget->setLayout(layout);
                ui->tableWidget->setCellWidget(i, j, widget);
            } else {
                QTableWidgetItem *item = new QTableWidgetItem(value.at(j));
                item->setTextAlignment(Qt::AlignCenter);
                ui->tableWidget->setItem(i, j, item);
            }
        }
    }
}

void frmModule8::start(int interval)
{
    this->loadRing();
    this->loadTable();

    //如果间隔太短表示不需要刷新,执行一次即可
    if (interval > 2000) {
        timer->start(interval);
    }
}

void frmModule8::stop()
{
    if (timer->isActive()) {
        timer->stop();
    }
}

Guess you like

Origin blog.csdn.net/feiyangqingyun/article/details/123796026