????????在開(kāi)始閱讀本文之前,如果您有學(xué)習(xí)創(chuàng)建Qt自定義控件并在其他項(xiàng)目中引用的需求,請(qǐng)參考:
Linux系統(tǒng)下在Qt Creator中創(chuàng)建自定義控件并在其他項(xiàng)目中引用https://blog.csdn.net/YMGogre/article/details/128920804
目錄
1、應(yīng)用場(chǎng)景:
2、所需資源:
3、界面布局:
3.1、各布局/控件屬性:
4、源代碼:
4.1、h文件
4.2、cpp文件
4.3、ui文件
5、使用方法:
6、注意事項(xiàng):
7、源碼下載:
1、應(yīng)用場(chǎng)景:
- 當(dāng)我們需要一個(gè)組合控件可以通過(guò)鍵盤(pán)輸入或者打開(kāi)Qt的顏色對(duì)話(huà)框來(lái)設(shè)置其他控件的顏色時(shí);
2、所需資源:
(無(wú),本質(zhì)即 Qt 的幾個(gè)自帶控件的組合)
3、界面布局:
整體布局如下圖所示,該自定義控件由一個(gè)GraphicsView、一個(gè)LineEdit、一個(gè)PushButton組成。窗口整體設(shè)置了 baseSize 為 140 × 25:
3.1、各布局/控件屬性:





4、源代碼:
4.1、h文件
/* mypalette.h */
#ifndef MYPALETTE_H
#define MYPALETTE_H
#include <QObject>
#include <QWidget>
#include <QColorDialog>
#include <QColor>
#include <QPalette>
#include <QString>
#include <QRegExpValidator>
#include <QtUiPlugin/QDesignerExportWidget>
#include <QEvent>
#include <QMouseEvent>
#include <QPushButton>
namespace Ui {
class MyPalette;
}
class QDESIGNER_WIDGET_EXPORT MyPalette : public QWidget
{
Q_OBJECT
public:
explicit MyPalette(QWidget *parent = nullptr);
~MyPalette();
QColor currentColor();
void setColor(int r, int g, int b, int a = 255);
void setColor(QColor color);
protected:
bool eventFilter(QObject *watchedm, QEvent *event) override; //重寫(xiě)事件過(guò)濾器方法
signals:
void colorchanged(QColor); //自定義顏色改變信號(hào)
private:
Ui::MyPalette *ui;
QColor color = QColor(Qt::white);
};
#endif // MYPALETTE_H
4.2、cpp文件
/* mypalette.cpp */
#include "mypalette.h"
#include "ui_mypalette.h"
MyPalette::MyPalette(QWidget *parent) :
QWidget(parent),
ui(new Ui::MyPalette)
{
ui->setupUi(this);
//QGraphicsView的鼠標(biāo)事件會(huì)傳遞給它所顯示的QGraphicsScene,然后再傳遞給場(chǎng)景中的QGraphicsItem。我們?cè)O(shè)置該控件屬性:傳遞給父對(duì)象做鼠標(biāo)事件處理
ui->ColorDisplay->setAttribute(Qt::WA_TransparentForMouseEvents);
/*****************************************
* 為自定義控件的子控件安裝該自定義控件的事件過(guò)濾器
****************************************/
ui->ColorLineEdit->installEventFilter(this);
ui->btn_SelectColor->installEventFilter(this);
/*使用正則表達(dá)式限制輸入(正確輸入格式應(yīng)當(dāng)形如 ———— "255; 255; 255",最后允許跟隨一個(gè)分號(hào)以及一個(gè)0~255的alpha通道值)
* (2[0-4][0-9];?\\s?) ———— 限制輸入200~249正整數(shù)(尾部允許跟隨0~1個(gè)分號(hào)";"和空格" ")
* (25[0-5];?\\s?) ———— 限制輸入250~255正整數(shù)(尾部允許跟隨0~1個(gè)分號(hào)";"和空格" ")
* (1[0-9][0-9];?\\s?) ———— 限制輸入100~199正整數(shù)(尾部允許跟隨0~1個(gè)分號(hào)";"和空格" ")
* ([1-9]?[0-9];?\\s?) ———— 限制輸入0~99正整數(shù)(尾部允許跟隨0~1個(gè)分號(hào)";"和空格" ")
*/
ui->ColorLineEdit->setValidator(new QRegExpValidator(QRegExp("^((2[0-4][0-9];\\s?)|(25[0-5];\\s?)|(1[0-9][0-9];\\s?)|([1-9]?[0-9];\\s?)){0,3}((2[0-4][0-9])|(25[0-5])|(1[0-9][0-9])|([1-9]?[0-9]))?$")));
connect(ui->ColorLineEdit, &QLineEdit::textChanged, this, [=](){
//使用正則表達(dá)式刪除字符串中所有空格
QString colorStr = ui->ColorLineEdit->text().remove(QRegExp("\\s"));
//使用split方法按";"分號(hào)分割字符串為字符串?dāng)?shù)組
QStringList colorStrList = colorStr.split(";");
//當(dāng)LineEdit只有rgb的值時(shí)
if(colorStrList.size() == 3)
{
//使用字符串?dāng)?shù)組內(nèi)容初始化一個(gè)QColor對(duì)象并賦值給color成員變量
color = QColor(colorStrList[0].toInt(), colorStrList[1].toInt(), colorStrList[2].toInt());
//當(dāng)顏色改變時(shí),發(fā)送“顏色改變信號(hào)”
emit colorchanged(color);
}
//當(dāng)LineEdit除了rgb的值還有alpha通道的值時(shí)
else if(colorStrList.size() == 4)
{
//使用字符串?dāng)?shù)組內(nèi)容初始化一個(gè)QColor對(duì)象并賦值給color成員變量
color = QColor(colorStrList[0].toInt(), colorStrList[1].toInt(), colorStrList[2].toInt(), colorStrList[3].toInt());
//當(dāng)顏色改變時(shí),發(fā)送“顏色改變信號(hào)”
emit colorchanged(color);
}
//獲取調(diào)色板
QPalette pal = ui->ColorDisplay->palette();
//設(shè)置調(diào)色板
pal.setColor(QPalette::Base, color);
//設(shè)置控件底色
ui->ColorDisplay->setPalette(pal);
});
//當(dāng)文本框編輯結(jié)束時(shí),根據(jù)color成員變量顯示其RGB字符串
connect(ui->ColorLineEdit, &QLineEdit::editingFinished, this, [=](){
//當(dāng)alpha通道值為255(默認(rèn))時(shí),LineEdit默認(rèn)不顯示alpha通道值
if(color.alpha() == 255)
{
QString colorStr = QString::number(color.red()) + "; " + QString::number(color.green()) + "; " + QString::number(color.blue());
ui->ColorLineEdit->setText(colorStr);
}
else
{
QString colorStr = QString::number(color.red()) + "; " + QString::number(color.green()) + "; " + QString::number(color.blue()) + "; " + QString::number(color.alpha());
ui->ColorLineEdit->setText(colorStr);
}
});
connect(ui->btn_SelectColor, &QPushButton::clicked, this, [=](){
//打開(kāi)一個(gè)顏色對(duì)話(huà)框并將其返回值交給局部變量_color
QColor _color = QColorDialog::getColor();
//判斷返回的顏色是否有效
if(_color.isValid())
{
//有效則改變顏色并發(fā)送信號(hào)
color = _color;
//當(dāng)顏色改變時(shí),發(fā)送“顏色改變信號(hào)”
emit colorchanged(color);
}
//根據(jù)對(duì)話(huà)框返回的顏色修改顏色展示方塊的顏色
QPalette pal = ui->ColorDisplay->palette();
//設(shè)置調(diào)色板
pal.setColor(QPalette::Base, color);
//設(shè)置控件底色
ui->ColorDisplay->setPalette(pal);
//根據(jù)對(duì)話(huà)框返回的顏色獲取RGB三色字符串
QString colorStr = QString::number(color.red()) + "; " + QString::number(color.green()) + "; " + QString::number(color.blue());
ui->ColorLineEdit->setText(colorStr);
});
}
/**
* @brief 獲取當(dāng)前顏色方法
* @return QColor ———— 返回當(dāng)前QColor顏色對(duì)象
*/
QColor MyPalette::currentColor()
{
return color;
}
/**
* @brief 設(shè)置顏色方法
* @param int r ———— 紅色
* @param int g ———— 綠色
* @param int b ———— 藍(lán)色
* @param int a ———— Alpha通道值(0完全透明~255完全不透明)
*/
void MyPalette::setColor(int r, int g, int b, int a)
{
if(a == 255)
{
//設(shè)置RGB三色字符串
QString colorStr = QString::number(r) + "; " + QString::number(g) + "; " + QString::number(b);
//setText()方法也會(huì)觸發(fā)QLineEdit的textChanged信號(hào)
ui->ColorLineEdit->setText(colorStr);
}
else
{
//設(shè)置RGB三色字符串
QString colorStr = QString::number(r) + "; " + QString::number(g) + "; " + QString::number(b) + "; " + QString::number(a);
//setText()方法也會(huì)觸發(fā)QLineEdit的textChanged信號(hào)
ui->ColorLineEdit->setText(colorStr);
}
}
/**
* @brief 設(shè)置顏色方法
* @param QColor color ———— QColor顏色對(duì)象
*/
void MyPalette::setColor(QColor color)
{
if(color.alpha() == 255)
{
//設(shè)置RGB三色字符串
QString colorStr = QString::number(color.red()) + "; " + QString::number(color.green()) + "; " + QString::number(color.blue());
//setText()方法也會(huì)觸發(fā)QLineEdit的textChanged信號(hào)
ui->ColorLineEdit->setText(colorStr);
}
else
{
//設(shè)置RGB三色字符串
QString colorStr = QString::number(color.red()) + "; " + QString::number(color.green()) + "; " + QString::number(color.blue()) + "; " + QString::number(color.alpha());
//setText()方法也會(huì)觸發(fā)QLineEdit的textChanged信號(hào)
ui->ColorLineEdit->setText(colorStr);
}
}
/**
* @brief 重寫(xiě)事件過(guò)濾器方法
* @attention 這里簡(jiǎn)要說(shuō)下為什么要重寫(xiě)該方法,這是因?yàn)楫?dāng)我們的自定義控件中有其他子控件時(shí),
* 點(diǎn)擊子控件的點(diǎn)擊響應(yīng)是相應(yīng)到子控件上的,而通常我們希望所有子控件的父對(duì)象(也就是自定義控
* 件本身)也會(huì)在點(diǎn)擊這些子控件時(shí)有響應(yīng)
* @param QMouseEvent *event ———— 事件對(duì)象
*/
bool MyPalette::eventFilter(QObject *watched, QEvent *event)
{
//攔截子控件的鼠標(biāo)按下或釋放事件
if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)
{
//QEvent類(lèi)型轉(zhuǎn)換為QMouseEvent類(lèi)型
QMouseEvent *mouseevent = static_cast<QMouseEvent *>(event);
this->QWidget::mousePressEvent(mouseevent); //調(diào)用基類(lèi)的mousePressEvent方法
//如果事件的被監(jiān)視對(duì)象是QPushButton
if(qobject_cast<QPushButton *>(watched))
this->setFocus(); //設(shè)置自定義控件本身獲得焦點(diǎn)
return false; //傳遞事件給子控件,讓其正常響應(yīng)點(diǎn)擊
//return true; //事件處理完畢(不傳遞事件給子控件,只響應(yīng)自定義控件本身被選中)
}
//其他類(lèi)型的事件交由基類(lèi)處理
return QWidget::eventFilter(watched, event);
}
MyPalette::~MyPalette()
{
delete ui;
}
4.3、ui文件
? UI文件僅能在設(shè)計(jì)模式下編輯,這里僅供布局參考!
<!-- mypalette.ui -->
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MyPalette</class>
<widget class="QWidget" name="MyPalette">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>299</width>
<height>188</height>
</rect>
</property>
<property name="baseSize">
<size>
<width>140</width>
<height>25</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,0">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGraphicsView" name="ColorDisplay">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="baseSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="ColorLineEdit">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="text">
<string>255; 255; 255</string>
</property>
<property name="maxLength">
<number>18</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_SelectColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="baseSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
5、使用方法:
- 顏色選擇組合控件封裝了一個(gè)自定義信號(hào) colorchanged,該信號(hào)會(huì)在顏色發(fā)生改變時(shí)被發(fā)送,使用該信號(hào)連接你的槽函數(shù)即可;
????????colorchanged?信號(hào)是一個(gè)帶參信號(hào),可以傳遞一個(gè) QColor 對(duì)象。比如說(shuō)我們可以通過(guò)類(lèi)似于以下的代碼去設(shè)置一個(gè) PushButton 控件的顏色:
connect(ui->myPalette, &MyPalette::colorchanged, this, [=](QColor color){ QPalette pal = ui->btn->palette(); //注:使用QPalette::Button枚舉值設(shè)置按鈕顏色時(shí),alpha通道值是無(wú)效的 pal.setColor(QPalette::Button, color); ui->btn->setPalette(pal); });
- 通過(guò) currentColor()?成員方法可以在代碼里獲取對(duì)象的顏色屬性,該方法返回一個(gè) QColor 對(duì)象;
- 通過(guò) setColor() 成員方法可以在代碼里設(shè)置對(duì)象的顏色屬性,該方法有一個(gè)重載;
????????當(dāng)然,setColor() 成員方法也會(huì)觸發(fā)發(fā)送 colorchanged 信號(hào)。
6、注意事項(xiàng):
請(qǐng)參考文章:Qt自定義控件 —— 子控件與父控件的鼠標(biāo)事件問(wèn)題https://blog.csdn.net/YMGogre/article/details/129357734
??本文提供的代碼是已經(jīng)解決了上面文章中涉及的問(wèn)題后的代碼。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-684858.html
7、源碼下載:
CSDN下載:Qt自定義控件-顏色選擇組合控件-C++文檔類(lèi)資源-CSDN文庫(kù)https://download.csdn.net/download/YMGogre/87541452文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-684858.html
到了這里,關(guān)于Qt自定義控件 —— 顏色選擇組合控件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!