Qt编写可视化大屏电子看板系统27-模块5负荷分布
一、前言
负荷分布模块包括工序计划负荷、当日负荷、负荷百分比三个子模块,工序计划负荷用表格的形式展示不同工序在不同日期的负荷工作时长,比如组装工序在 2022-02-10 运行了88小时,一般表格显示最近的一星期的信息;当日负荷用柱状图的形式显示不同工序当天的负荷运行时长;负荷百分比用折线图展示,其中包括了定位线默认放在100的值位置。
子模块表名对应表:
| 子模块标题 | 子模块表名 |
|---|---|
| 工序计划负荷 | t_5_1_work_load |
| 当日负荷 | t_5_2_work_load_today |
| 负荷百分比 | t_5_3_work_load_percent |
1 工序计划负荷
表名:t_5_1_work_load
| 字段名 | 中文名 | 类型 | 长度 | 说明 |
|---|---|---|---|---|
| internal_id | 序号 | INTEGER | 11 | 主键自增 |
| process_name | 工序名称 | VARCHAR | 255 | |
| work_load_1 | 第1天负荷 | VARCHAR | 255 | |
| work_load_* | 第*天负荷 | VARCHAR | 255 | |
| work_load_7 | 第7天负荷 | VARCHAR | 255 |
默认数据:
| internal_id | process_name | work_load_1 | work_load_2 | work_load_3 | work_load_4 | work_load_5 | work_load_6 | work_load_7 |
|---|---|---|---|---|---|---|---|---|
| 1 | CNC粗 | 101H | 81H | 90H | 120H | 30H | 60H | 120H |
| 2 | CNC精 | 102H | 102H | 120H | 81H | 45H | 102H | 81H |
| 3 | EDM | 77H | 102H | 90H | 102H | 45H | 90H | 120H |
| 4 | WEDM | 87H | 102H | 120H | 45H | 102H | 102H | 90H |
| 5 | 抛光 | 45H | 102H | 102H | 90H | 81H | 81H | 81H |
| 6 | 钳工 | 89H | 90H | 45H | 120H | 120H | 120H | 102H |
| 7 | 组装 | 77H | 90H | 81H | 102H | 45H | 102H | 81H |
表名:t_5_1_work_load_table_head
这个设计很巧妙,相当于动态的日期和数据,日期作为标题。
| 字段名 | 中文名 | 类型 | 长度 | 说明 |
|---|---|---|---|---|
| internal_id | 序号 | INTEGER | 11 | 主键自增 |
| date_1 | 第1天日期 | VARCHAR | 255 | |
| date_2 | 第2天日期 | VARCHAR | 255 | |
| date_3 | 第3天日期 | VARCHAR | 255 | |
| date_4 | 第4天日期 | VARCHAR | 255 | |
| date_5 | 第5天日期 | VARCHAR | 255 | |
| date_6 | 第6天日期 | VARCHAR | 255 | |
| date_7 | 第7天日期 | VARCHAR | 255 |
默认数据:
| internal_id | date_1 | date_2 | date_3 | date_4 | date_5 | date_6 | date_7 |
|---|---|---|---|---|---|---|---|
| 1 | 2019-04-30 | 2019-05-01 | 2019-05-02 | 2019-05-03 | 2019-05-04 | 2019-05-05 | 2019-05-06 |
2 当日负荷
表名:t_5_2_work_load_today
| 字段名 | 中文名 | 类型 | 长度 | 说明 |
|---|---|---|---|---|
| internal_id | 序号 | INTEGER | 11 | 主键自增 |
| group_name | 分组名称 | REAL | 11 | 小数位精度1 |
| green | 绿色值 | REAL | 11 | 小数位精度1 |
| red | 红色值 | REAL | 11 | 小数位精度1 |
默认数据:
| internal_id | group_name | green | red |
|---|---|---|---|
| 1 | CNC粗 | 20 | 20 |
| 2 | CNC精 | 40 | 20 |
| 3 | EDM | 60 | 0 |
| 4 | WEDM | 30.2 | 2 |
| 5 | 铣床 | 40 | 0 |
| 6 | 磨床 | 30 | 50 |
3 负荷百分比
表名:t_5_3_work_load_percent
| 字段名 | 中文名 | 类型 | 长度 | 说明 |
|---|---|---|---|---|
| internal_id | 序号 | INTEGER | 11 | 主键自增 |
| group_name | 分组名称 | VARCHAR | 255 | |
| day_1 | 第1天 | INTEGER | 3 | |
| day_* | 第*天 | INTEGER | 3 | |
| day_7 | 第7天 | INTEGER | 3 |
默认数据:
| internal_id | group_name | day_1 | day_2 | day_3 | day_4 | day_5 | day_6 | day_7 |
|---|---|---|---|---|---|---|---|---|
| 1 | CNC粗 | 70 | 80 | 90 | 70 | 50 | 99 | 80 |
| 2 | CNC精 | 120 | 100 | 130 | 140 | 90 | 100 | 85 |
| 3 | EDM | 120 | 100 | 120 | 80 | 90 | 40 | 50 |
| 4 | WEDM | 100 | 120 | 120 | 100 | 100 | 80 | 70 |
| 5 | 铣床 | 90 | 80 | 75 | 40 | 12 | 30 | 10 |
| 6 | 磨床 | 80 | 70 | 50 | 60 | 40 | 50 | 30 |
二、功能特点
- 采用分层设计,整体总共分三级界面,一级界面是整体布局,二级界面是单个功能模块,三级界面是单个控件。
- 子控件包括饼图、圆环图、曲线图、柱状图、柱状分组图、横向柱状图、横向柱状分组图、合格率控件、百分比控件、进度控件、设备状态面板、表格数据、地图控件、视频控件等。
- 二级界面可以自由拖动悬浮,支持最小化隐藏、最大化关闭、响应双击自定义标题栏。
- 数据源支持模拟数据(默认)、数据库采集、串口通信(需定制)、网络通信(需定制)、网络请求等,可自由设定每个子界面的采集间隔即数据刷新频率。
- 采用纯QWidget编写,亲测Qt4.6到Qt6.2任意版本,理论上支持后续其他Qt版本。
- 超强跨平台,亲测windows、linux、mac、国产uos、国产银河麒麟kylin等系统,效果完美,同时还支持嵌入式linux比如树莓派、香橙派、全志、imx6等。
- 同时集成了自定义控件、qchart饼图、echart地图等功能。
- 内置多套配色风格样式(紫色、蓝色、深蓝、黑色),默认紫色,自适应任意分辨率。
- 可设置系统标题、目标分辨率、布局方案,启动立即应用。
- 可设置主背景颜色、面板颜色、十字线游标颜色等各种颜色。
- 可设置多条曲线不同颜色,没有设置颜色的情况下内置多套精美颜色随机应用。
- 可设置标题栏背景颜色、文字颜色。
- 可设置曲线图表背景颜色、文字颜色、网格颜色。
- 可设置正常颜色、警戒颜色、报警颜色、禁用颜色、百分比进度颜色。
- 可分别设置各种字体大小,比如全局字体、软件名称、标题栏、子标题栏、加粗标签等。
- 可设置标题栏高度、表头高度、行高度。
- 曲线支持游标、定位线、悬停高亮数据点、悬停显示值。
- 柱状图支持顶部(可设置顶端、上部、中间、底部)显示数据,全部自适应计算位置。
- 支持平滑曲线,内置多种平滑曲线算法,还支持面积图平滑。
- 面积图填充颜色可选多种规则比如单色透明度填充、透明度渐变填充等。
- 数据库支持sqlite、mysql、postgresql、oracle、国产人大金仓等数据库。
- 主界面直接鼠标右键切换布局、配色方案、关闭开启某个二级窗体。
- 自动记忆所有子窗口的大小和位置,下次启动立即应用。
- 动态加载布局方案菜单,可以动态新建布局、恢复布局、保存布局、另存布局等,用户可以制造任意布局。
- 二级窗体,双击从主窗体分离出来浮动,可以自由调整大小。再次双击标题栏最大化,再次双击还原。
- 子模块也可以全屏显示作为一个大屏,这样就可以一个大屏拓展出多个子大屏,放大查看子模块的数据详情,适用多屏展示。
- 每个模块都可以自定义采集速度,如果是数据库采集会自动排队处理,后期还可以拓展每个子模块都独立的数据库采集。
- 提供系统设置模块进行整体的配置参数设置,效果立即应用。
- 提供精美炫酷的大屏地图模块,包括静态图片、闪烁效果、迁徙效果、世界地图、区域地图等,可指定点的经纬度坐标,识别单击响应,可以做地图跳转等,每个点都可以不同的颜色和提示信息。
- 除了提供大屏系统外,还将每个模块都做了独立的模块示例界面,每个模块都可以独立学习使用,里面用到的控件也单独做了控件示例界面,方便学习每个控件如何使用。
- 非常详细的开发和使用手册,其中包括数据库说明、模块对照图、控件对照图、项目结构、代码说明(精确到每个类)、演示demo、使用方法等。
三、体验地址
- 体验地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取码:01jf 文件名:bin_bigscreen.zip。
- 国内站点:https://gitee.com/feiyangqingyun
- 国际站点:https://github.com/feiyangqingyun
- 个人主页:https://blog.csdn.net/feiyangqingyun
- 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
- 在线文档:https://feiyangqingyun.gitee.io/qwidgetdemo/bigscreen/
四、效果图

五、核心代码
#include "frmmodule5.h"
#include "ui_frmmodule5.h"
#include "quihelper.h"
#include "progressthree.h"
frmModule5::frmModule5(QWidget *parent) : QWidget(parent), ui(new Ui::frmModule5)
{
ui->setupUi(this);
this->initForm();
this->initTable();
this->initPlot1();
this->initPlot2();
}
frmModule5::~frmModule5()
{
delete ui;
}
void frmModule5::initForm()
{
//设置对应的属性应用特定样式
ui->labTitle1->setProperty("flag", "title");
ui->labTitle2->setProperty("flag", "title");
ui->labTitle3->setProperty("flag", "title");
ui->widgetSub1->setProperty("flag", "sub");
ui->widgetSub2->setProperty("flag", "sub");
ui->widgetSub3->setProperty("flag", "sub");
//定时器模拟数据
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(loadTable()));
connect(timer, SIGNAL(timeout()), this, SLOT(loadPlot1()));
connect(timer, SIGNAL(timeout()), this, SLOT(loadPlot2()));
//绑定信号槽处理接收的数据+发送执查询语句
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)));
//绑定样式改变信号重新加载数据
connect(AppEvent::Instance(), SIGNAL(changeStyle()), this, SLOT(start()));
}
void frmModule5::receiveData(const QString &tag, const QStringList &data, int mesc)
{
int count = data.count();
if (tag == "t_5_1_work_load") {
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);
value << QString("100|0|0");
values << value;
}
loadTable(values);
}
} else if (tag == "t_5_2_work_load_today") {
if (count % 3 == 0) {
rowNames1.clear();
vdouble value1, value2;
for (int i = 0; i < count; i = i + 3) {
rowNames1 << data.at(i);
value1 << data.at(i + 1).toDouble();
value2 << data.at(i + 2).toDouble();
}
loadPlot1(lvdouble() << value1 << value2);
}
} else if (tag == "t_5_3_work_load_percent") {
if (count % 8 == 0) {
lineNames.clear();
vstring lab;
lab << "1" << "2" << "3" << "4" << "5" << "6" << "7";
vdouble key;
key << 0 << 1 << 2 << 3 << 4 << 5 << 6;
//取出总共行数
int row = count / 8;
lvdouble values;
for (int i = 0; i < row; i++) {
for (int j = (8 * i); j < (8 * i) + 1; j++) {
lineNames << data.at(j);
}
double max = 8 * (i + 1);
vdouble value;
for (int j = (8 * i) + 1; j < max; j++) {
value << data.at(j).toDouble();
}
values << value;
}
loadPlot2(lab, key, values);
}
} else if (tag == "t_5_1_work_load_table_head") {
if (count == 7) {
QStringList headText;
headText << "工序";
for (int i = 0; i < count; i++) {
headText << data.at(i);
}
ui->tableWidget->setHorizontalHeaderLabels(headText);
}
}
}
void frmModule5::initTable()
{
QStringList headText;
headText << "工序" << "4月1日" << "4月2日" << "4月3日" << "4月4日" << "4月5日" << "4月6日" << "4月7日" << "进度" << "";
int columnCount = headText.count();
ui->tableWidget->setColumnCount(columnCount);
ui->tableWidget->setHorizontalHeaderLabels(headText);
ui->tableWidget->horizontalHeader()->setMinimumHeight(AppConfig::HeadHeight);
ui->tableWidget->verticalHeader()->setDefaultSectionSize(AppConfig::RowHeight);
//计算值的宽度
int width = 100;
if (QUIHelper::deskWidth() <= 1440) {
width = 80;
}
if (AppConfig::WorkMode != "timer") {
width = 110;
}
ui->tableWidget->setColumnWidth(0, 80);
ui->tableWidget->setColumnWidth(columnCount - 2, 120);
ui->tableWidget->setColumnHidden(columnCount - 2, true);
for (int i = 1; i < columnCount - 1; i++) {
ui->tableWidget->setColumnWidth(i, width);
}
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 frmModule5::loadTable()
{
QStringList list;
list << "process_name";
for (int i = 1; i <= 7; i++) {
list << QString("work_load_%1").arg(i);
}
QString tableName = "t_5_1_work_load";
QString columnName = list.join(",");
//读取表头
list.clear();
for (int i = 1; i <= 7; i++) {
list << QString("date_%1").arg(i);
}
QString tableName2 = "t_5_1_work_load_table_head";
QString columnName2 = list.join(",");
if (AppConfig::WorkMode == "timer") {
lstringl values;
int rowCount = 9;
ui->tableWidget->setRowCount(rowCount);
for (int i = 0; i < rowCount; i++) {
QStringList value;
value << QString(QUIHelper::getRandValue(1, 3) == 1 ? "CNC粗" : "CNC精");
value << QString("%1H").arg(QUIHelper::getRandValue(50, 150));
value << QString("%1H").arg(QUIHelper::getRandValue(100, 150));
value << QString("%1H").arg(QUIHelper::getRandValue(50, 150));
value << QString("%1H").arg(QUIHelper::getRandValue(100, 150));
value << QString("%1H").arg(QUIHelper::getRandValue(80, 150));
value << QString("%1H").arg(QUIHelper::getRandValue(100, 150));
value << QString("%1H").arg(QUIHelper::getRandValue(100, 150));
value << QString("%1|%2|0").arg(QUIHelper::getRandValue(10, 50)).arg(QUIHelper::getRandValue(10, 50));
values << value;
}
loadTable(values);
} else if (AppConfig::WorkMode == "db") {
DbData::DbLocal->select(tableName, columnName, true);
DbData::DbLocal->select(tableName2, columnName2, true);
} else if (AppConfig::WorkMode == "http") {
DbData::DbHttp->select(tableName, columnName, true);
DbData::DbHttp->select(tableName2, columnName2, true);
}
}
void frmModule5::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);
//增加widget+布局巧妙实现居中
QWidget *widget = new QWidget;
QHBoxLayout *layout = new QHBoxLayout;
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
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 frmModule5::initPlot1()
{
rowNames1 << "CNC粗" << "CNC精" << "EDM" << "WEDM" << "铣床" << "磨床";
columnNames1 << "系列1" << "系列2";
}
void frmModule5::loadPlot1()
{
QString tableName = "t_5_2_work_load_today";
QString columnName = "group_name,green,red";
if (AppConfig::WorkMode == "timer") {
vdouble value1, value2;
for (int i = 0; i < 6; i++) {
value1 << QUIHelper::getRandValue(20, 50);
value2 << QUIHelper::getRandValue(20, 50);
}
loadPlot1(lvdouble() << value1 << value2);
} else if (AppConfig::WorkMode == "db") {
DbData::DbLocal->select(tableName, columnName, true);
} else if (AppConfig::WorkMode == "http") {
DbData::DbHttp->select(tableName, columnName, true);
}
}
void frmModule5::loadPlot1(const lvdouble &values)
{
ui->customPlot1->clear();
double maxY = CustomPlotHelper::getMaxValue2(values) * 1.2;
ui->customPlot1->setRangeX(0.5, rowNames1.count() + 0.5);
ui->customPlot1->setRangeY(0, maxY, AppConfig::StepY);
//设置柱状数据结构体
BarData data;
data.rowNames = rowNames1;
data.columnNames = columnNames1;
data.values = values;
data.borderColor = AppConfig::ColorChartText;
data.valuePosition = 0;
data.valuePrecision = 0;
data.valueColor = AppConfig::ColorChartText;
ui->customPlot1->setDataBars(data);
ui->customPlot1->replot();
}
void frmModule5::initPlot2()
{
lineNames << "CNC粗" << "CNC精" << "EDM" << "WEDM" << "铣床" << "磨床";
ui->customPlot2->setLegend(true, 7, 3);
}
void frmModule5::loadPlot2()
{
QStringList list;
list << "group_name";
for (int i = 1; i <= 7; i++) {
list << QString("day_%1").arg(i);
}
QString tableName = "t_5_3_work_load_percent";
QString columnName = list.join(",");
if (AppConfig::WorkMode == "timer") {
vstring lab;
lab << "1" << "2" << "3" << "4" << "5" << "6" << "7";
vdouble key, value1, value2, value3, value4, value5, value6;
key << 0 << 1 << 2 << 3 << 4 << 5 << 6;
int dataCount = lab.count();
for (int i = 0; i < dataCount; i++) {
value1 << QUIHelper::getRandValue(10, 150);
value2 << QUIHelper::getRandValue(10, 150);
value3 << QUIHelper::getRandValue(10, 150);
value4 << QUIHelper::getRandValue(10, 150);
value5 << QUIHelper::getRandValue(10, 150);
value6 << QUIHelper::getRandValue(10, 150);
}
loadPlot2(lab, key, lvdouble() << value1 << value2 << value3 << value4 << value5 << value6);
} else if (AppConfig::WorkMode == "db") {
DbData::DbLocal->select(tableName, columnName, true);
} else if (AppConfig::WorkMode == "http") {
DbData::DbHttp->select(tableName, columnName, true);
}
}
void frmModule5::loadPlot2(const vstring &lab, const vdouble &key, const lvdouble &values)
{
if (AppConfig::StaticLine) {
ui->customPlot2->drawStaticLineh(-0.5, 100, AppConfig::ColorLine);
}
int count = values.count();
ui->customPlot2->getPlot()->clearGraphs();
ui->customPlot2->addGraph(count);
LineData data;
data.key = key;
for (int i = 0; i < count; i++) {
data.index = i;
data.name = lineNames.at(i);
data.value = values.at(i);
//设置线条颜色,可以指定颜色也可以随机颜色
data.lineColor = ui->customPlot2->getColors().at(i);
ui->customPlot2->setDataLine(data);
}
//设置坐标轴范围值+X坐标对应显示文字
double maxY = CustomPlotHelper::getMaxValue(values) * 1.5;
ui->customPlot2->setLabX(key, lab);
ui->customPlot2->setRangeX(-0.5, key.count() - 0.5);
ui->customPlot2->setRangeY(0, maxY, AppConfig::StepY, AppConfig::ShowPercent);
ui->customPlot2->replot();
}
void frmModule5::start(int interval)
{
this->loadPlot1();
this->loadPlot2();
this->loadTable();
//如果间隔太短表示不需要刷新,执行一次即可
if (interval > 2000) {
timer->start(interval);
}
}
void frmModule5::stop()
{
if (timer->isActive()) {
timer->stop();
}
}
Qt编写可视化大屏电子看板系统27-模块5负荷分布的更多相关文章
- Qt编写数据可视化大屏界面电子看板13-基础版
一.前言 之前发布的Qt编写的可视化大屏电子看板系统,很多开发者比较感兴趣,也收到了很多反馈意见,纵观市面上的大屏系统,基本上都是B/S结构的web版本,需要在后台进行自定义配置模块,绑定数据源等,其 ...
- Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)
一.自定义控件大全 (一).控件介绍 超过160个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...
- Qt编写数据可视化大屏界面电子看板2-配色方案
一.前言 做完整个数据可视化大屏界面电子看板系统后,为了提升点逼格,需要提供好几套默认的风格样式以供选择,这样用户可以选择自己喜欢的配色方案来作为整个系统的颜色方案,去看了下市面上大部分的大屏电子看板 ...
- Qt编写安防视频监控系统9-自动隐藏光标
一.前言 这个效果的灵感来自于大屏电子看板系统,在很多系统中尤其是上了大屏的时候,其实在用户不在操作的时候,是很不希望看到那个鼠标箭头指针的,只有当用户操作的时候才显示出来,这个就需要开个定时器定时计 ...
- Qt编写数据可视化大屏界面电子看板系统
一.前言 目前大屏大数据可视化UI这块非常火,趁热也用Qt来实现一个,Qt这个一站式超大型GUI超市,没有什么他做不了的,大屏电子看板当然也不在话下,有了QSS和QPainter这两个无敌的工具组合, ...
- Qt编写数据可视化大屏界面电子看板12-数据库采集
一.前言 数据采集是整个数据可视化大屏界面电子看板系统核心功能,没有数据源,这仅仅是个玩具UI,没啥用,当然默认做了定时器模拟数据,产生随机数据,这个可以直接配置文件修改来选择采用何种数据采集方法,总 ...
- Qt编写数据可视化大屏界面电子看板11-自定义控件
一.前言 说到自定义控件,我是感觉特别熟悉的几个字,本人亲自原创的自定义控件超过110个,都是来自各个行业的具体应用真实需求,而不是凭空捏造的,当然有几个小控件也有点凑数的嫌疑,在编写整个数据可视化大 ...
- Qt编写数据可视化大屏界面电子看板8-调整间距
一.前言 在数据可视化大屏界面电子看板系统中,前期为了使用目标客户机,调整间距是必不可少的工作,QMainWindow中的QDockWidget,会默认生成布局和QSplitter调整宽高大小,鼠标移 ...
- Qt编写数据可视化大屏界面电子看板4-布局另存
一.前言 布局另存是数据可视化大屏界面电子看板系统中的额外功能之一,主要用于有时候用户需要在现有布局上做个微调,然后直接将该布局另存为一个布局配置文件使用,可以省略重新新建布局重新来一次大的调整的工作 ...
- Qt编写数据可视化大屏界面电子看板3-新建布局
一.前言 能够新建布局,也是数据可视化大屏界面电子看板系统中的必备功能之一,新建布局这样的功能一般做到右键菜单中,单击新建布局菜单,弹出输入框要求输入新的布局的名称,为了更符合国情,直接支持中文名称, ...
随机推荐
- .net 泛型 Generic
什么是泛型 就是不确定的类型
- 6.flask 源码解析:响应
目录 一.flask 源码解析:响应 1.1 response 简介 1.2 flask 响应(response) 1.3 werkzeug response 1.4 自定义 response Fla ...
- 在 Ubuntu 22.04 上安装 KubeSphere 实战教程
作者:老 Z,中电信数智科技有限公司山东分公司运维架构师,云原生爱好者,目前专注于云原生运维,云原生领域技术栈涉及 Kubernetes.KubeSphere.DevOps.OpenStack.Ans ...
- 云原生周刊:CNCF 宣布 KubeEdge 毕业
云原生周刊:CNCF 宣布 KubeEdge 毕业 开源项目推荐 Watchtower Watchtower 这个项目能够自动监测并更新正在运行的 Docker 容器.它会定期检查并拉取 Docker ...
- SQL Server创建用户只能访问指定数据库和视图
我们在给数据库用户赋予权限时,有时候不想让该用户看到太多过程表和过程视图,这时就需要限定用户的访问权限 第一步:创建用户 创建数据库连接后,进入安全性--登录名,单击右键,新建登录名,并设置默认数据库 ...
- Centos7安装部署prometheus
普罗米修斯的主要特点是: 具有由度量名称和键/值对标识的时间序列数据的多维数据模型 PromQL,一种灵活的查询语言, 可以利用这一维度 不依赖分布式存储; 单个服务器节点是自治的 时间序列集合通过H ...
- VMware安装Ubuntu操作系统 2024.9.27
1.安装 Ubuntu的官方网站是:https://www.ubuntu.com/download 点进去可以直接下载 文件下载会比较慢,我这点用了约5分钟 然后就可以打开vmware,选择: 就可以 ...
- java通过SSE实现消息推送
一.什么是SSE 严格地说,HTTP 协议无法做到服务器主动推送信息.但是,有一种变通方法,就是服务器向客户端声明,接下来要发送的是流信息(streaming). 也就是说,发送的不是一次性的数据包, ...
- 2.搭建K8S集群前置知识
搭建K8S集群 搭建k8s环境平台规划 单master集群 单个master节点,然后管理多个node节点 多master集群 多个master节点,管理多个node节点,同时中间多了一个负载均衡的过 ...
- 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-5-创建首个自动化脚本(详细教程)
1.简介 前面几篇宏哥介绍了两种(java和maven)环境搭建和浏览器的启动方法,这篇文章宏哥将要介绍第一个自动化测试脚本.前边环境都搭建成功了,浏览器也驱动成功了,那么我们不着急学习其他内容,首先 ...