Qt编写数据可视化大屏界面电子看板3

Stella981
• 阅读 745

一、前言

能够新建布局,也是数据可视化大屏界面电子看板系统中的必备功能之一,新建布局这样的功能一般做到右键菜单中,单击新建布局菜单,弹出输入框要求输入新的布局的名称,为了更符合国情,直接支持中文名称,保存成配置文件直接中文名称命名,这样方便用户理解,Qt5以来对乱码的问题解决的就比较好了,不像Qt4时代稍不留神就乱码了,Qt5只要保证源码文件utf-8编码基本上就很少遇到乱码问题了。新建布局必须要有个默认的窗体排列,Qt中的dock窗体,默认布局会以窗体的sizehint作为大小参照标准,也不一定是完全正确的,还跟窗体中的子控件有关系,不过这些都不影响布局以后重新从配置文件加载的布局,QMainWindow提供saveState()函数直接保存当前窗体的所有布局位置大小等信息到配置文件,至于配置文件的内容格式,那是人类无法理解的格式,反正我是看不懂,这些都没有关系的,你重新用restoreState()函数加载读取配置文件的信息时,会自动应用,这样就很爽很完美了。

二、电子看板介绍

电子看板是目视化管理的一种表现形式,即对数据的状况一目了然地表现,主要是对于管理项目,它通过利用形象直观而又色彩适宜的各种视觉感知信息来组织现场生产活动,目视管理依据人类的生理特征,在生产现场充分利用信号灯、标识牌、符号颜色等方式来发出视觉信号,鲜明准确地刺激人的神经末梢,快速地传递信息,形象直观地将潜在的问题和浪费现象都显现出来。以便任何人都可以及时掌握管理现状和必要的情报,从而能够快速制定并实施应对措施。因此,管理看板是发现问题、解决问题的非常有效且直观的手段,是优秀的现场管理必不可少的工具之一。

三、功能特点

  1. 整体总共分三级界面,一级界面是整体布局,二级界面是单个功能模块,三级界面是单个控件。
  2. 子控件包括饼图+圆环图+曲线图+柱状图+柱状分组图+横向柱状图+横向柱状分组图+合格率控件+百分比控件+进度控件+设备状态面板+表格数据+地图控件+视频控件+其他控件等。
  3. 二级界面可以自由拖动悬浮,支持最小化最大化关闭,响应双击自定义标题栏。
  4. 数据源支持数据库采集(默认)、网络通信、网络请求等,可自由设定每个子界面的采集间隔即数据刷新频率。
  5. 采用纯QWidget编写,支持Qt4.6到Qt5.12.3任何版本,支持嵌入式linux比如树莓派、香橙派、全志、imx6等。
  6. 提供三个内核版本,自定义控件版本+qchart版本+echart版本。
  7. 内置多套配色风格样式,默认紫色,支持任何分辨率。
  8. 可设置标题+目标分辨率+布局方案,启动立即应用。
  9. 可设置主背景颜色+面板颜色+十字线游标颜色。
  10. 可设置多条曲线颜色,没有设置颜色的情况下内置15套精美颜色随机应用。
  11. 可设置标题栏背景颜色+文字颜色。
  12. 可设置曲线图表背景颜色+文字颜色+网格颜色。
  13. 可设置正常颜色+警戒颜色+报警颜色+禁用颜色+百分比进度颜色。
  14. 可分别设置各种字体大小,比如全局+软件名称+标题栏+子标题栏+加粗标签等。
  15. 可设置标题栏高度+表头高度+行高度。
  16. 曲线支持游标+悬停高亮数据点和显示值,柱状图支持顶部(可设置顶端+上部+中间+底部)显示数据,全部自适应计算位置。
  17. 主界面直接鼠标右键切换布局+配色方案+关闭开启某个二级窗体。
  18. 自动记忆所有子窗口的大小和位置,下次启动立即应用。
  19. 动态加载布局方案菜单,可以动态新建布局、恢复布局、保存布局、另存布局等,用户可以制造任意布局。
  20. 二级窗体,双击从主窗体分离出来浮动,可以自由调整大小。再次双击标题栏最大化,再次双击还原。
  21. 每个模块都可以自定义采集速度,如果是数据库采集会自动排队处理。

四、配置文件说明

(1)、基本配置参数

字段

描述

默认值

WorkMode

工作模式 timer-模拟数据 db-数据库采集 tcp-网络采集 http-post请求

timer

Title

软件标题,显示在软件中间顶部

数字化工厂信息中心

Ratio

分辨率,目前无意义

4096*216

Layout

布局方案,每次切换布局方案以后都会保存

完整布局

Theme

配色方案,每次切换配色方案以后都会保存

紫色风格

VideoAddr

视频流地址,视频模块播放的视频地址

凤凰卫视

AutoRun

是否开机启动

false

MoveEnable

模块是否可以拖动,启用以后模块可以任意拖动

true

CutLeftBottom

底部布局左侧是否切掉

true

CutRightBottom

底部布局右侧是否切掉

true

StaticLine

是否绘制静态定位线,为假则绘制游标十字线

true

(2)、颜色配置参数

字段

描述

默认值

ColorMainBg

主背景颜色

QColor(4, 7, 38)

ColorPanelBg

面板背景颜色

QColor(26, 29, 60)

ColorLine

十字线定位线颜色

QColor(255, 0, 0)

ColorLine1

线条1颜色

QColor(0, 176, 180)

ColorLine2

线条2颜色

QColor(32, 159, 223)

ColorLine3

线条3颜色

QColor(255, 192, 0)

ColorTitleBg

标题栏背景颜色

QColor(48, 48, 85)

ColorTitleText

标题栏文字颜色

QColor(255, 255, 255)

ColorChartBg

曲线图表背景颜色

QColor(38, 41, 74)

ColorChartText

曲线图表文字颜色

QColor(250, 250, 250)

ColorChartGrid

曲线图表网格颜色

QColor(180, 180, 180)

ColorOk

正常颜色

QColor(0, 176, 180)

ColorLow

警戒颜色

QColor(255, 192, 0)

ColorAlarm

报警颜色

QColor(214, 77, 84)

ColorDisable

禁用背景颜色

QColor(210, 210, 210)

ColorPercent

环形百分比背景颜色

QColor(0, 254, 254)

(3)、字体和尺寸配置参数

字段

描述

默认值

MainFont

全局字号

微软雅黑,12

NameFont

软件名称字号

19

LabFont

加粗标签字号

12

DeviceFont

设备面板字号

12

SubTitleFont

模块子标题栏字号

13

TitleFont

模块标题栏字号

15

TitleHeight

模块标题栏高度

23

HeadHeight

表格表头高度

28

RowHeight

表格行高度

25

(4)、采集速度配置参数

字段

描述

默认值

IntervalModule1

模块1采集间隔

5000

IntervalModule2

模块2采集间隔

5000

IntervalModule3

模块3采集间隔

5000

IntervalModule4

模块4采集间隔

5000

IntervalModule5

模块5采集间隔

5000

IntervalModule6

模块6采集间隔

5000

IntervalModule7

模块7采集间隔

5000

IntervalModule8

模块8采集间隔

5000

(5)、本地数据库配置参数

字段

描述

默认值

LocalDBType

本地数据库类型,Sqlite、Mysql等

Mysql

LocalDBIP

本地数据库主机地址

127.0.0.1

LocalDBPort

本地数据库端口

3306

LocalDBName

本地数据库名称

bigscreen

LocalUserName

本地数据库用户名

root

LocalUserPwd

本地数据库密码,以密文存储

root

五、特别说明

  1. 可执行文件同级文件夹有layout+layout_1440+layout_1920,程序默认自动识别分辨率并加载对应的布局文件夹,比如1920分辨率则从layout_1920文件夹加载布局,并作为整体布局文件夹。
  2. 程序默认是模拟数据,如果需要从数据库采集则修改配置文件WorkMode=db即可。
  3. 如果发现布局拖动乱了,可以直接鼠标右键选择恢复布局即可,在保存布局以前。
  4. 在中间地图模块鼠标右键可以弹出菜单,切换布局和配色方案等。
  5. 在模块的标题栏上右键可以弹出默认的dock菜单,用来显示和隐藏各模块。
  6. 软件关闭过程中会自动保存布局,下次启动以后自动应用。
  7. 如果使用的默认的默认的配色方案比如紫色风格,则配置文件中的颜色全部无效,会自动应用代码中的颜色,如果需要启用自定义的颜色,则将配置文件的 Theme=\x81ea\x5b9a\x4e49\x98ce\x683c 即可。此时打开软件会应用配置文件中的颜色。
  8. 右键菜单可以截图保存,默认命名为 配色方案名称_布局方案名称.png 保存在snap目录下。
  9. 如果是XP系统请先执行fixff.cmd,用来修复ffmpeg在XP上不可用的BUG。
  10. 可执行文件下载地址:https://pan.baidu.com/s/1o97IGvZgTgDhlkuXQa4B0w 提取码:r2bv ,会不定期更新程序,欢迎各位提出批评和建议。

六、效果图

Qt编写数据可视化大屏界面电子看板3

七、核心代码

#include "frmmodulecenter.h"
#include "ui_frmmodulecenter.h"
#include "quiwidget.h"

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

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

bool frmModuleCenter::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == this) {
        if (event->type() == QEvent::MouseButtonPress) {
            if (qApp->mouseButtons() == Qt::RightButton) {
                menuMain->exec(QCursor::pos());
            }
        }
    }

    return QWidget::eventFilter(watched, event);
}

void frmModuleCenter::initForm()
{
    ui->labName->setText(App::Title);
    this->installEventFilter(this);

    //鼠标右键菜单
    menuMain = new QMenu(this);

    //从目录下找布局文件自动生成菜单
    menuLayout = menuMain->addMenu("布局方案");
    QDir dir(QUIHelper::appPath() + "/layout");
    QStringList files = dir.entryList(QStringList() << "*.ini");
    foreach (QString file, files) {
        QString name = file.split(".").first();
        menuLayout->addAction(name, this, SLOT(changeLayout()));
    }

    menuTheme = menuMain->addMenu("配色方案");
    menuTheme->addAction("紫色风格", this, SLOT(changeTheme()));
    menuTheme->addAction("蓝色风格", this, SLOT(changeTheme()));
    menuTheme->addAction("深蓝风格", this, SLOT(changeTheme()));
    menuTheme->addAction("黑色风格", this, SLOT(changeTheme()));
    menuTheme->addAction("自定义风格", this, SLOT(changeTheme()));
    menuMain->addSeparator();

    menuMain->addAction("新建布局", this, SLOT(doAction()));
    menuMain->addAction("恢复布局", this, SLOT(doAction()));
    menuMain->addAction("保存布局", this, SLOT(doAction()));
    menuMain->addAction("布局另存", this, SLOT(doAction()));
    menuMain->addSeparator();

    menuMain->addAction("截取屏幕", this, SLOT(doAction()));
    menuMain->addAction("退出系统", this, SLOT(doAction()));

    //设置菜单允许复选框+选中配置文件对应菜单
    actionLayout = menuLayout->actions();
    foreach (QAction *action, actionLayout) {
        action->setCheckable(true);
        action->setChecked(action->text() == App::Layout);
    }

    actionTheme = menuTheme->actions();
    foreach (QAction *action, actionTheme) {
        action->setCheckable(true);
        action->setChecked(action->text() == App::Theme);
    }
}

void frmModuleCenter::changeLayout()
{
    QAction *ac = (QAction *)sender();
    emit changeLayout(ac->text());
    foreach (QAction *action, actionLayout) {
        action->setChecked(action == ac);
    }
}

void frmModuleCenter::changeTheme()
{
    QAction *ac = (QAction *)sender();
    emit changeTheme(ac->text());
    foreach (QAction *action, actionTheme) {
        action->setChecked(action == ac);
    }
}

void frmModuleCenter::addLayout(const QString &layout, int type)
{
    if (!layout.isEmpty()) {
        //判断名称不能重复
        foreach (QAction *action, actionLayout) {
            if (action->text() == layout) {
                QUIHelper::showMessageBoxError("布局已经存在,请重新输入!", 3);
                return;
            }
        }

        //增加右键菜单中的布局子菜单
        QAction *action = menuLayout->addAction(layout, this, SLOT(changeLayout()));
        //取消原有所有选中
        foreach (QAction *action, actionLayout) {
            action->setChecked(false);
        }

        action->setCheckable(true);
        action->setChecked(true);
        actionLayout.append(action);
        emit saveLayout(layout, type);
    }
}

void frmModuleCenter::doAction()
{
    QAction *action = (QAction *)sender();
    QString text = action->text();

    if (text == "新建布局") {
        QString layout = QUIHelper::showInputBox("布局名称");
        addLayout(layout, 0);
    } else if (text == "恢复布局") {
        emit saveLayout("", 1);
    } else if (text == "保存布局") {
        if (QUIHelper::showMessageBoxQuestion("确定要保存吗?保存后不可恢复!") == QMessageBox::Yes) {
            emit saveLayout(App::Layout, 2);
            QUIHelper::showMessageBoxInfo("恭喜,保存当前布局成功!", 3);
        }
    } else if (text == "布局另存") {
        QString layout = QUIHelper::showInputBox("布局名称");
        addLayout(layout, 3);
    } else if (text == "截取屏幕") {
        QWidget *w = (QWidget *)this->parent();
        if (w == 0) {
            return;
        }

        QPixmap pix;
        int x = 0;
        int y = 0;
        int width = w->width() - 0;
        int height = w->height() - 0;

#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
        pix = pix.grabWindow(w->winId(), x, y, width, height);
#else
        QScreen *pscreen = QApplication::primaryScreen();
        pix = pscreen->grabWindow(w->winId(), x, y, width, height);
#endif

        QString file = QString("%1/snap/%2_%3.png").arg(QUIHelper::appPath()).arg(App::Theme).arg(App::Layout);
        pix.save(file, "png");
    } else if (text == "退出系统") {
        emit closeAll();
    }
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Java修道之路,问鼎巅峰,我辈代码修仙法力齐天
<center<fontcolor00FF7Fsize5face"黑体"代码尽头谁为峰,一见秃头道成空。</font<center<fontcolor00FF00size5face"黑体"编程修真路破折,一步一劫渡飞升。</font众所周知,编程修真有八大境界:1.Javase练气筑基2.数据库结丹3.web前端元婴4.Jav
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Qt编写数据可视化大屏界面电子看板12
一、前言数据采集是整个数据可视化大屏界面电子看板系统核心功能,没有数据源,这仅仅是个玩具UI,没啥用,当然默认做了定时器模拟数据,产生随机数据,这个可以直接配置文件修改来选择采用何种数据采集方法,总结了一下基本上会有这样几种数据源,timer模拟数据db数据库采集tcp网络采集httppost请求,大量的web会选择采用http作
Stella981 Stella981
3年前
Qt编写自定义控件16
前言五一期间一直忙着大屏电子看板软件的开发,没有再去整理控件,今天已经将大屏电子看板的所有子窗口都实现了任意停靠和双击独立再次双击最大化等功能,过阵子有空再写一篇文章介绍其中的技术点。魔法老鼠控件,来自Qt自带的demo,我只是将其修改了部分颜色接口等。实现的功能1:可设置身体眼睛眼珠鼻子尾巴的颜色2:
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这