Qt編寫數據可視化大屏界面電子看板11-自定義控件

1、前言

說到自定義控件,我是感受特別熟悉的幾個字,本人親自原創的自定義控件超過110個,都是來自各個行業的具體應用真實需求,而不是憑空捏造的,固然有幾個小控件也有點湊數的嫌疑,在編寫整個數據可視化大屏界面電子看板系統中,也用到了四五個自定義的控件,好比那個環形百分比圖,多態進度條,合格率儀表盤,速度儀表盤等,這些控件在現有的類中是沒有的,須要用QPainter這個牛逼的工具來繪製,相似於神筆馬良似的,給我一個畫筆,能夠畫出任意你想要的圖形,比如我常說的心中有座標,萬物皆painter。linux

自定義控件爲了適應總體換膚,須要用Q_PROPERTY類指定,相似於元對象,用Q_PROPERTY指定的東西,能夠直接樣式表控制,好比GaugePercent{qproperty-baseColor:#FF0000;}就能夠對全部的GaugePercent類進行顏色更換,並且是動態更換,用Q_PROPERTY指定的東西還能夠直接出如今Qtcreator的右側屬性欄,直接修改屬性便可,所見即所得,很是方便。sql

2、電子看板介紹

電子看板是目視化管理的一種表現形式,即對數據的情況一目瞭然地表現,主要是對於管理項目,它經過利用形象直觀而又色彩適宜的各類視覺感知信息來組織現場生產活動,目視管理依據人類的生理特徵,在生產現場充分利用信號燈、標識牌、符號顏色等方式來發出視覺信號,鮮明準確地刺激人的神經末梢,快速地傳遞信息,形象直觀地將潛在的問題和浪費現象都顯現出來。以便任何人均可以及時掌握管理現狀和必要的情報,從而可以快速制定並實施應對措施。所以,管理看板是發現問題、解決問題的很是有效且直觀的手段,是優秀的現場管理必不可少的工具之一。數據庫

3、功能特色

  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. 每一個模塊均可以自定義採集速度,若是是數據庫採集會自動排隊處理。

4、配置文件說明

(1)、基本配置參數

字段 描述 默認值
WorkMode 工做模式 timer-模擬數據 db-數據庫採集 tcp-網絡採集 http-post請求 db
MapStyle 中間地圖樣式 image-靜態圖片 point-閃爍點 move-遷徙圖 point
Title 軟件標題,顯示在軟件中間頂部 數字化工廠信息中心
Ratio 分辨率,目前無心義 4096*216
Layout 佈局方案,每次切換佈局方案之後都會保存 完整佈局
Theme 配色方案,每次切換配色方案之後都會保存 紫色風格
VideoAddr 視頻流地址,視頻模塊播放的視頻地址 鳳凰衛視
AutoRun 是否開機啓動 false
MoveEnable 模塊是否能夠拖動,啓用之後模塊能夠任意拖動 true
CutLeftBottom 底部佈局左側是否切掉 true
CutRightBottom 底部佈局右側是否切掉 true
StaticLine 是否繪製靜態定位線,爲假則繪製遊標十字線 true
ShowPercent Y軸是否顯示百分比 true
StepY Y軸大尺度步長 6
CursorHideTime 用戶不操做鼠標自動隱藏鼠標的時間間隔,單位秒 5

(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

5、特別說明

  1. 可執行文件同級文件夾有layout+layout_1440+layout_1920,程序默認自動識別分辨率並加載對應的佈局文件夾,好比1920分辨率則從layout_1920文件夾加載佈局,並做爲總體佈局文件夾。
  2. 程序默認是模擬數據,若是須要從數據庫採集則修改配置文件WorkMode=db便可。
  3. 若是發現佈局拖動亂了,能夠直接鼠標右鍵選擇恢復佈局便可,在保存佈局之前。
  4. 在中間地圖模塊鼠標右鍵能夠彈出菜單,切換佈局和配色方案等。
  5. 在模塊的標題欄上右鍵能夠彈出默認的dock菜單,用來顯示和隱藏各模塊。
  6. 軟件關閉過程當中會自動保存佈局,下次啓動之後自動應用。
  7. 若是使用的默認的默認的配色方案好比紫色風格,則配置文件中的顏色所有無效,會自動應用代碼中的顏色,若是須要啓用自定義的顏色,則將配置文件的 Theme=x81eax5b9ax4e49x98cex683c 便可。此時打開軟件會應用配置文件中的顏色。
  8. 右鍵菜單能夠截圖保存,默認命名爲 配色方案名稱_佈局方案名稱.png 保存在snap目錄下。
  9. 若是是XP系統請先執行fixff.cmd,用來修復ffmpeg在XP上不可用的BUG。
  10. 在二級窗體的標題欄上右鍵彈出模塊菜單,能夠對單個模塊打開關閉,其餘地方右鍵全局菜單。
  11. 可執行文件下載地址:https://pan.baidu.com/s/1o97I... 提取碼:r2bv。
  12. 會不按期更新程序,歡迎各位提出批評和建議。

6、效果圖

7、核心代碼

void ProgressRing::paintEvent(QPaintEvent *)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    //繪製準備工做,啓用反鋸齒,平移座標軸中心,等比例縮放
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.translate(width / 2, height / 2);
    painter.scale(side / 200.0, side / 200.0);

    //繪製背景
    drawBg(&painter);
    //繪製進度
    drawRing(&painter);

    //繪製間隔,從新繪製一個圓遮住,產生間距效果
    if (ringPadding > 0) {
        drawPadding(&painter);
    }

    //繪製中間圓
    drawCircle(&painter);
    //繪製當前值
    drawValue(&painter);
}

void ProgressRing::drawBg(QPainter *painter)
{
    int radius = 99;
    painter->save();
    painter->setPen(Qt::NoPen);
    //這裏有個技巧,若是沒有間距則設置成圓環的背景色
    painter->setBrush(ringPadding == 0 ? ringBgColor : bgColor);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->restore();
}

void ProgressRing::drawRing(QPainter *painter)
{
    int radius = 99 - ringPadding;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(ringColor);

    QRectF rect(-radius, -radius, radius * 2, radius * 2);

    //計算總範圍角度,當前值範圍角度,剩餘值範圍角度
    double angleAll = 360.0;
    double angleCurrent = angleAll * ((currentValue - minValue) / (maxValue - minValue));
    double angleOther = angleAll - angleCurrent;

    //若是逆時針
    if (!clockWise) {
        angleCurrent = -angleCurrent;
        angleOther = -angleOther;
    }

    //動態設置當前進度顏色
    QColor color = ringColor;
    if (alarmMode == 1) {
        if (currentValue >= ringValue3) {
            color = ringColor3;
        } else if (currentValue >= ringValue2) {
            color = ringColor2;
        } else {
            color = ringColor1;
        }
    } else if (alarmMode == 2) {
        if (currentValue <= ringValue1) {
            color = ringColor1;
        } else if (currentValue <= ringValue2) {
            color = ringColor2;
        } else {
            color = ringColor3;
        }
    }

    //繪製當前值餅圓
    painter->setBrush(color);
    painter->drawPie(rect, (startAngle - angleCurrent) * 16, angleCurrent * 16);

    //繪製剩餘值餅圓
    painter->setBrush(ringBgColor);
    painter->drawPie(rect, (startAngle - angleCurrent - angleOther) * 16, angleOther * 16);

    painter->restore();
}

void ProgressRing::drawPadding(QPainter *painter)
{
    int radius = 99 - ringWidth - ringPadding;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(bgColor);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->restore();
}

void ProgressRing::drawCircle(QPainter *painter)
{
    //文字的區域要減去進度的寬度及間距
    int radius = 99 - ringWidth - (ringPadding * 2);
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(circleColor);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->restore();
}

void ProgressRing::drawValue(QPainter *painter)
{
    //文字的區域要減去進度的寬度及間距
    int radius = 99 - ringWidth - (ringPadding * 2);
    painter->save();
    painter->setPen(textColor);

    QFont font;
    int fontSize = radius - (showPercent ? 20 : 6);
    font.setPixelSize(fontSize);
    painter->setFont(font);

    QRectF textRect(-radius, -radius, radius * 2, radius * 2);
    QString strValue;
    if (showPercent) {
        double percent = (currentValue * 100) / (maxValue - minValue);
        strValue = QString("%1%").arg(percent, 0, 'f', precision);
    } else {
        strValue = QString("%1").arg(currentValue, 0, 'f', precision);
    }

    //若是定義了顯示的文字則優先顯示
    strValue = text.isEmpty() ? strValue : text;
    painter->drawText(textRect, Qt::AlignCenter, strValue);

    painter->restore();
}
相關文章
相關標籤/搜索