生活随笔
收集整理的這篇文章主要介紹了
Qt编写可视化大屏电子看板系统1-布局方案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、前言
布局方案在整個數據可視化大屏界面電子看板系統中,是除了基礎功能以外的核心功能之一,只有具備了布局方案這個功能,才能讓用戶隨意調整自己想要的布局,保存成自定義名稱的布局配置文件,這樣就大大增加了靈活性,可以更好的適應各種分辨率,畢竟客戶的電腦運行環境各種各樣的都有,模塊數量眾多,有些不想展示,有些需要特別放大展示,有些需要偶爾全屏展示等,這些布局用戶都可以自己定義好保存配置方案,存儲到指定的目錄下,下次啟動會自動生成對應的布局菜單文件讓用戶自行選擇切換。
二、電子看板介紹
電子看板是目視化管理的一種表現形式,即對數據的狀況一目了然地表現,主要是對于管理項目,它通過利用形象直觀而又色彩適宜的各種視覺感知信息來組織現場生產活動,目視管理依據人類的生理特征,在生產現場充分利用信號燈、標識牌、符號顏色等方式來發出視覺信號,鮮明準確地刺激人的神經末梢,快速地傳遞信息,形象直觀地將潛在的問題和浪費現象都顯現出來。以便任何人都可以及時掌握管理現狀和必要的情報,從而能夠快速制定并實施應對措施。因此,管理看板是發現問題、解決問題的非常有效且直觀的手段,是優秀的現場管理必不可少的工具之一。
三、功能特點
采用分層設計,整體總共分三級界面,一級界面是整體布局,二級界面是單個功能模塊,三級界面是單個控件。子控件包括餅圖、圓環圖、曲線圖、柱狀圖、柱狀分組圖、橫向柱狀圖、橫向柱狀分組圖、合格率控件、百分比控件、進度控件、設備狀態面板、表格數據、地圖控件、視頻控件等。二級界面可以自由拖動懸浮,支持最小化隱藏、最大化關閉、響應雙擊自定義標題欄。數據源支持模擬數據(默認)、數據庫采集、串口通信(需定制)、網絡通信(需定制)、網絡請求等,可自由設定每個子界面的采集間隔即數據刷新頻率。采用純QWidget編寫,親測Qt4.6到Qt6.2任意版本,理論上支持后續其他Qt版本。超強跨平臺,親測windows、linux、mac、國產uos、國產銀河麒麟kylin等系統,效果完美,同時還支持嵌入式linux比如樹莓派、香橙派、全志、imx6等。同時集成了自定義控件、qchart餅圖、echart地圖等功能。內置多套配色風格樣式(紫色、藍色、深藍、黑色),默認紫色,自適應任意分辨率。可設置系統標題、目標分辨率、布局方案,啟動立即應用。可設置主背景顏色、面板顏色、十字線游標顏色等各種顏色。可設置多條曲線不同顏色,沒有設置顏色的情況下內置多套精美顏色隨機應用。可設置標題欄背景顏色、文字顏色。可設置曲線圖表背景顏色、文字顏色、網格顏色。可設置正常顏色、警戒顏色、報警顏色、禁用顏色、百分比進度顏色。可分別設置各種字體大小,比如全局字體、軟件名稱、標題欄、子標題欄、加粗標簽等。可設置標題欄高度、表頭高度、行高度。曲線支持游標、定位線、懸停高亮數據點、懸停顯示值。柱狀圖支持頂部(可設置頂端、上部、中間、底部)顯示數據,全部自適應計算位置。支持平滑曲線,內置多種平滑曲線算法,還支持面積圖平滑。面積圖填充顏色可選多種規則比如單色透明度填充、透明度漸變填充等。數據庫支持sqlite、mysql、postgresql、oracle、國產人大金倉等數據庫。主界面直接鼠標右鍵切換布局、配色方案、關閉開啟某個二級窗體。自動記憶所有子窗口的大小和位置,下次啟動立即應用。動態加載布局方案菜單,可以動態新建布局、恢復布局、保存布局、另存布局等,用戶可以制造任意布局。二級窗體,雙擊從主窗體分離出來浮動,可以自由調整大小。再次雙擊標題欄最大化,再次雙擊還原。子模塊也可以全屏顯示作為一個大屏,這樣就可以一個大屏拓展出多個子大屏,放大查看子模塊的數據詳情,適用多屏展示。每個模塊都可以自定義采集速度,如果是數據庫采集會自動排隊處理,后期還可以拓展每個子模塊都獨立的數據庫采集。提供系統設置模塊進行整體的配置參數設置,效果立即應用。提供精美炫酷的大屏地圖模塊,包括靜態圖片、閃爍效果、遷徙效果、世界地圖、區域地圖等,可指定點的經緯度坐標,識別單擊響應,可以做地圖跳轉等,每個點都可以不同的顏色和提示信息。除了提供大屏系統外,還將每個模塊都做了獨立的模塊示例界面,每個模塊都可以獨立學習使用,里面用到的控件也單獨做了控件示例界面,方便學習每個控件如何使用。非常詳細的開發和使用手冊,其中包括數據庫說明、模塊對照圖、控件對照圖、項目結構、代碼說明(精確到每個類)、演示demo、使用方法等。
四、配置文件說明
(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 |
五、特別說明
執行文件同級文件夾有layout+layout_1440+layout_1920,程序默認自動識別分辨率并加載對應的布局文件夾,比如1920分辨率則從layout_1920文件夾加載布局,并作為整體布局文件夾。程序默認是模擬數據,如果需要從數據庫采集則修改配置文件WorkMode=db即可。如果發現布局拖動亂了,可以直接鼠標右鍵選擇恢復布局即可,在保存布局以前。在中間地圖模塊鼠標右鍵可以彈出菜單,切換布局和配色方案等。在模塊的標題欄上右鍵可以彈出默認的dock菜單,用來顯示和隱藏各模塊。軟件關閉過程中會自動保存布局,下次啟動以后自動應用。如果使用的默認的默認的配色方案比如紫色風格,則配置文件中的顏色全部無效,會自動應用代碼中的顏色,如果需要啟用自定義的顏色,則將配置文件的 Theme=\x81ea\x5b9a\x4e49\x98ce\x683c 即可。此時打開軟件會應用配置文件中的顏色。右鍵菜單可以截圖保存,默認命名為 配色方案名稱_布局方案名稱.png 保存在snap目錄下。如果是XP系統請先執行fixff.cmd,用來修復ffmpeg在XP上不可用的BUG。可執行文件下載地址:https://pan.baidu.com/s/1o97IGvZgTgDhlkuXQa4B0w 提取碼:r2bv ,會不定期更新程序,歡迎各位提出批評和建議。
六、效果圖
七、核心代碼
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "quiwidget.h"
#include "appinit.h"
#include "customtitlebar.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);this->initForm();this->changeLayout(App::Layout, true);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::closeEvent(QCloseEvent *)
{closeAll();
}void MainWindow::initForm()
{this->setWindowTitle(App::Title);//this->setProperty("canMove", true);this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);//自動根據分辨率找合適的默認的布局文件夾layoutPath = QUIHelper::appPath() + "/layout";if (QUIHelper::deskWidth() == 1440) {QDir dir(QUIHelper::appPath() + "/layout_1440");if (dir.exists()) {layoutPath = QUIHelper::appPath() + "/layout_1440";}} else if (QUIHelper::deskWidth() == 1920) {QDir dir(QUIHelper::appPath() + "/layout_1920");if (dir.exists()) {layoutPath = QUIHelper::appPath() + "/layout_1920";}}module1 = new frmModule1;module2 = new frmModule2;module3 = new frmModule3;module4 = new frmModule4;module5 = new frmModule5;module6 = new frmModule6;module7 = new frmModule7;module8 = new frmModule8;moduleCenter = new frmModuleCenter;moduleVideo = new frmModuleVideo;//啟動模擬數據或者數據采集module1->start(App::IntervalModule1);module2->start(App::IntervalModule2);module3->start(App::IntervalModule3);module4->start(App::IntervalModule4);module5->start(App::IntervalModule5);module6->start(App::IntervalModule6);module7->start(App::IntervalModule7);module8->start(App::IntervalModule8);//實例化停靠窗體newWidget(module1, "年度產量匯總");newWidget(module2, "當月計劃達成率");newWidget(module3, "設備監控");newWidget(module4, "模具進度");newWidget(module5, "負荷分布");newWidget(module6, "送檢一次合格率");newWidget(module7, "品質管理");newWidget(module8, "物料管理");newWidget(moduleVideo, "視頻監控");QList<QWidget *> widgets;widgets << module1 << module2 << module3 << module4 << module5 << module6 << module7 << module8 << moduleCenter << moduleVideo;connect(moduleCenter, SIGNAL(changeLayout(QString)), this, SLOT(changeLayout(QString)));connect(moduleCenter, SIGNAL(saveLayout(QString, int)), this, SLOT(saveLayout(QString, int)));connect(moduleCenter, SIGNAL(changeTheme(QString)), this, SLOT(changeTheme(QString)));connect(moduleCenter, SIGNAL(closeAll()), this, SLOT(closeAll()));//設置拉伸策略for (int i = 0; i < widgets.count(); i++) {widgets.at(i)->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);}//設置中心窗體this->setCentralWidget(moduleCenter);//設置停靠參數,不允許重疊,只允許拖動this->setDockOptions(QMainWindow::AnimatedDocks);//將底部左側作為左側區域,底部右側作為右側區域,否則底部區域會填充拉伸if (App::CutLeftBottom) {setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);}if (App::CutRightBottom) {setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);}
}void MainWindow::clearWidget()
{for (int i = 0; i < widgets.count(); i++) {this->removeDockWidget(widgets.at(i));}
}void MainWindow::initWidget()
{//添加左側窗體addWidget(widgets.at(0), 0);addWidget(widgets.at(7), 0);addWidget(widgets.at(3), 0);//添加右側窗體addWidget(widgets.at(6), 1);addWidget(widgets.at(4), 1);addWidget(widgets.at(5), 1);//添加底部窗體addWidget(widgets.at(2), 3);addWidget(widgets.at(1), 3);addWidget(widgets.at(8), 3);
}void MainWindow::newWidget(QWidget *widget, const QString &title)
{//自定義停靠窗體標題欄QString objName = widget->objectName();CustomTitleBar *titleBar = new CustomTitleBar;titleBar->setObjectName("titleBar_" + objName);titleBar->setTitle(title);//實例化停靠窗體QDockWidget *dockWidget = new QDockWidget;dockWidget->setObjectName("dockWidget_" + objName);dockWidget->setWindowTitle(title);dockWidget->setTitleBarWidget(titleBar);dockWidget->setWidget(widget);//如果設置了不可移動則只允許關閉if (!App::MoveEnable) {dockWidget->setFeatures(QDockWidget::DockWidgetClosable);}//設置頂部不可停靠dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea);widgets << dockWidget;
}void MainWindow::addWidget(QDockWidget *widget, int position)
{//設置停靠位置Qt::DockWidgetArea area;if (position == 0) {area = Qt::LeftDockWidgetArea;} else if (position == 1) {area = Qt::RightDockWidgetArea;} else if (position == 2) {area = Qt::TopDockWidgetArea;} else if (position == 3) {area = Qt::BottomDockWidgetArea;}this->addDockWidget(area, widget);//如果是首次生成布局則需要全部可見QString file = QString("%1/%2.ini").arg(layoutPath).arg(App::Layout);if (!QFile(file).exists()) {widget->setVisible(true);}
}void MainWindow::changeLayout(const QString &layout, bool init)
{//首次加載不需要比較是否和配置文件一樣bool needLoad = init;if (!init && App::Layout != layout) {needLoad = true;//先保存原有布局saveLayout(App::Layout, 2);}if (needLoad) {App::Layout = layout;App::writeConfig();this->clearWidget();this->initWidget();this->initLayout(App::Layout);//全屏+QWebEngineView控件一起會產生右鍵菜單無法彈出的BUG,需要上移一個像素QRect rect = qApp->desktop()->screenGeometry();
#if 1rect.setY(-1);rect.setHeight(rect.height());
#elserect.setX(30);rect.setY(40);rect.setWidth(1370);rect.setHeight(795);
#endifthis->setGeometry(rect);}
}void MainWindow::initLayout(const QString &layout)
{QString file = QString("%1/%2.ini").arg(layoutPath).arg(layout);QSettings set(file, QSettings::IniFormat);set.beginGroup("MainWindow");restoreState(set.value("State").toByteArray());set.endGroup();
}//type: 0-新建布局 1-恢復布局 2-保存布局 3-布局另存
void MainWindow::saveLayout(const QString &layout, int type)
{//如果為空則表示是恢復布局if (type == 0) {App::Layout = layout;this->changeLayout(App::Layout, true);return;} else if (type == 1) {this->changeLayout(App::Layout, true);return;}QString file = QString("%1/%2.ini").arg(layoutPath).arg(layout);QSettings set(file, QSettings::IniFormat);set.beginGroup("MainWindow");set.setValue("State", saveState());set.endGroup();App::Layout = layout;App::writeConfig();
}void MainWindow::changeTheme(const QString &theme)
{//必須是風格改變了才需要重新應用if (App::Theme != theme) {App::Theme = theme;App::writeConfig();AppInit::Instance()->initTheme();AppInit::Instance()->initStyle();}
}void MainWindow::closeAll()
{saveLayout(App::Layout, 2);QUIHelper::sleep(100);exit(0);
}
總結
以上是生活随笔為你收集整理的Qt编写可视化大屏电子看板系统1-布局方案的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。