天天看點

qt creator 設定按鍵顔色_Qt編寫自定義控件30-顔色多态按鈕 一、前言二、實作的功能三、效果圖四、核心代碼六、控件介紹

一、前言

這個控件一開始打算用樣式表來實作,經過初步的探索,後面發現還是不夠智能以及不能完全滿足需求,比如要在此控件設定多個角标,這個用QSS就很難實作,後面才慢慢研究用QPainter來繪制,我記得當時接到這個定制控件任務的時候是2016年,那時候對QPainter的使用還不是很熟悉,也就是從此控件開始,逐漸研究QPainter的繪制,把所有的内置函數都使用一遍,最終用的越來越熟悉,使得後來到了心中有坐标,萬物皆painter的境界,可能就像武林中所說的打通了任督二脈吧。

本控件除了可以設定正常的圓角角度,邊框寬度,邊框顔色,正常顔色,按下顔色以外,還可以設定各個角标和正文文字内容/字型/對齊方式/顔色,同時還要提供三種顔色展示模式,松開按下兩種顔色,按下松開顔色上下交替,按下松開顔色漸變交替。QLinearGradient是個好東西,各種顔色交替效果全靠它來實作。

二、實作的功能

* 1:可設定圓角角度,邊框寬度

* 2:可設定角标和正文文字内容/字型/對齊方式/顔色

* 3:可設定邊框顔色,正常顔色,按下顔色

* 4:可設定背景圖檔

* 5:可設定按鈕顔色模式

三、效果圖

qt creator 設定按鍵顔色_Qt編寫自定義控件30-顔色多态按鈕 一、前言二、實作的功能三、效果圖四、核心代碼六、控件介紹

四、核心代碼

bool ColorButton::eventFilter(QObject *watched, QEvent *event){ if (!isEnabled()) { return QWidget::eventFilter(watched, event); } static QPoint lastPoint; if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *e = static_cast(event); if (this->rect().contains(e->pos()) && (e->button() == Qt::LeftButton)) { lastPoint = e->pos(); isPressed = true; update(); } } else if (event->type() == QEvent::MouseMove && isPressed && canMove) { QMouseEvent *e = static_cast(event); int dx = e->pos().x() - lastPoint.x(); int dy = e->pos().y() - lastPoint.y(); this->move(this->x() + dx, this->y() + dy); return true; } else if (event->type() == QEvent::MouseButtonRelease && isPressed) { isPressed = false; update(); } return QWidget::eventFilter(watched, event);}void ColorButton::paintEvent(QPaintEvent *){ //繪制準備工作,啟用反鋸齒 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); //繪制背景 drawBg(&painter); //繪制文字 drawText(&painter);}void ColorButton::drawBg(QPainter *painter){ painter->save(); //設定邊框顔色及寬度 QPen pen; pen.setColor(borderColor); pen.setWidthF(borderWidth); painter->setPen(pen); //繪制區域要減去邊框寬度 QRect rect; rect.setX(borderWidth); rect.setY(borderWidth); rect.setWidth(width() - borderWidth * 2); rect.setHeight(height() - borderWidth * 2); //如果背景圖檔存在則顯示背景圖檔,否則顯示背景色 if (!bgImage.isNull()) { //等比例縮放繪制 QPixmap img = bgImage.scaled(rect.width(), rect.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); painter->drawPixmap((this->rect().width() - img.width()) / 2, (this->rect().height() - img.height()) / 2, img); } else { if (colorMode == ColorMode_Normal) { if (isPressed) { painter->setBrush(QBrush(pressedColor)); } else { painter->setBrush(QBrush(normalColor)); } } else if (colorMode == ColorMode_Replace) { QLinearGradient gradient(QPoint(0, 0), QPoint(0, height())); if (isPressed) { gradient.setColorAt(0.0, pressedColor); gradient.setColorAt(0.49, pressedColor); gradient.setColorAt(0.50, normalColor); gradient.setColorAt(1.0, normalColor); } else { gradient.setColorAt(0.0, normalColor); gradient.setColorAt(0.49, normalColor); gradient.setColorAt(0.50, pressedColor); gradient.setColorAt(1.0, pressedColor); } painter->setBrush(gradient); } else if (colorMode == ColorMode_Shade) { QLinearGradient gradient(QPoint(0, 0), QPoint(0, height())); if (isPressed) { gradient.setColorAt(0.0, pressedColor); gradient.setColorAt(1.0, normalColor); } else { gradient.setColorAt(0.0, normalColor); gradient.setColorAt(1.0, pressedColor); } painter->setBrush(gradient); } painter->drawRoundedRect(rect, borderRadius, borderRadius); } painter->restore();}void ColorButton::drawText(QPainter *painter){ if (!bgImage.isNull()) { return; } painter->save(); //如果要顯示角标,則重新計算顯示文字的區域 if (showSuperText) { int offset = 3; QRect rect; rect.setX(borderWidth * offset); rect.setY(borderWidth); rect.setWidth(width() - borderWidth * offset * 2); rect.setHeight(height() - borderWidth * 2); Qt::Alignment alignment = Qt::AlignCenter; if (superTextAlign == TextAlign_Top_Left) { alignment = Qt::AlignTop | Qt::AlignLeft; } else if (superTextAlign == TextAlign_Top_Center) { alignment = Qt::AlignTop | Qt::AlignHCenter; } else if (superTextAlign == TextAlign_Top_Right) { alignment = Qt::AlignTop | Qt::AlignRight; } else if (superTextAlign == TextAlign_Center_Left) { alignment = Qt::AlignLeft | Qt::AlignVCenter; } else if (superTextAlign == TextAlign_Center_Center) { alignment = Qt::AlignHCenter | Qt::AlignVCenter; } else if (superTextAlign == TextAlign_Center_Right) { alignment = Qt::AlignRight | Qt::AlignVCenter; } else if (superTextAlign == TextAlign_Bottom_Left) { alignment = Qt::AlignBottom | Qt::AlignLeft; } else if (superTextAlign == TextAlign_Bottom_Center) { alignment = Qt::AlignBottom | Qt::AlignHCenter; } else if (superTextAlign == TextAlign_Bottom_Right) { alignment = Qt::AlignBottom | Qt::AlignRight; } //繪制角标 painter->setPen(superTextColor); painter->setFont(superTextFont); painter->drawText(rect, alignment, superText); } int offset = 5; QRect rect; rect.setX(borderWidth * offset); rect.setY(borderWidth); rect.setWidth(width() - borderWidth * offset * 2); rect.setHeight(height() - borderWidth * 2); Qt::Alignment alignment = Qt::AlignCenter; if (textAlign == TextAlign_Top_Left) { alignment = Qt::AlignTop | Qt::AlignLeft; } else if (textAlign == TextAlign_Top_Center) { alignment = Qt::AlignTop | Qt::AlignHCenter; } else if (textAlign == TextAlign_Top_Right) { alignment = Qt::AlignTop | Qt::AlignRight; } else if (textAlign == TextAlign_Center_Left) { alignment = Qt::AlignLeft | Qt::AlignVCenter; } else if (textAlign == TextAlign_Center_Center) { alignment = Qt::AlignHCenter | Qt::AlignVCenter; } else if (textAlign == TextAlign_Center_Right) { alignment = Qt::AlignRight | Qt::AlignVCenter; } else if (textAlign == TextAlign_Bottom_Left) { alignment = Qt::AlignBottom | Qt::AlignLeft; } else if (textAlign == TextAlign_Bottom_Center) { alignment = Qt::AlignBottom | Qt::AlignHCenter; } else if (textAlign == TextAlign_Bottom_Right) { alignment = Qt::AlignBottom | Qt::AlignRight; } painter->setPen(textColor); painter->setFont(textFont); painter->drawText(rect, alignment, text); painter->restore();}
           

六、控件介紹

1. 超過149個精美控件,涵蓋了各種儀表盤、進度條、進度球、指南針、曲線圖、标尺、溫度計、導覽列、導航欄,flatui、高亮按鈕、滑動選擇器、農曆等。遠超qwt內建的控件數量。

2. 每個類都可以獨立成一個單獨的控件,零耦合,每個控件一個頭檔案和一個實作檔案,不依賴其他檔案,友善單個控件以源碼形式內建到項目中,較少代碼量。qwt的控件類環環相扣,高度耦合,想要使用其中一個控件,必須包含所有的代碼。

3. 全部純Qt編寫,QWidget+QPainter繪制,支援Qt4.6到Qt5.12的任何Qt版本,支援mingw、msvc、gcc等編譯器,支援任意作業系統比如windows+linux+mac+嵌入式linux等,不亂碼,可直接內建到Qt Creator中,和自帶的控件一樣使用,大部分效果隻要設定幾個屬性即可,極為友善。

4. 每個控件都有一個對應的單獨的包含該控件源碼的DEMO,友善參考使用。同時還提供一個所有控件使用的內建的DEMO。

5. 每個控件的源代碼都有詳細中文注釋,都按照統一設計規範編寫,友善學習自定義控件的編寫。

6. 每個控件預設配色和demo對應的配色都非常精美。

7. 超過130個可見控件,6個不可見控件。

8. 部分控件提供多種樣式風格選擇,多種訓示器樣式選擇。

9. 所有控件自适應窗體拉伸變化。

10. 內建自定義控件屬性設計器,支援拖曳設計,所見即所得,支援導入導出xml格式。

11. 自帶activex控件demo,所有控件可以直接運作在ie浏覽器中。

12. 內建fontawesome圖形字型+阿裡巴巴iconfont收藏的幾百個圖形字型,享受圖形字型帶來的樂趣。

13. 所有控件最後生成一個dll動态庫檔案,可以直接內建到qtcreator中拖曳設計使用。

14. 目前已經有qml版本,後期會考慮出pyqt版本,如果使用者需求量很大的話。

繼續閱讀