大家在统一的QT项目中进行开发,为了使用统一的主题和界面风格,通常采用QSS来设置统一的风格。但是QSS设置的风格有时也不是我们想要的,达不到我们想要的效果。但是自定义控件可以满足我们的需求,而且把定义好的控件分发到各个项目成员中的Qt Desiner中,每个成员只需要在设计界面的时候,直接拖动就可以了。如下图自定义了一个按钮。
1.首先需要自定义一个按钮控件:
#pragma once
#include <QtUiPlugin/QDesignerExportWidget>
#include <QtWidgets/QWidget>
class wcButtonPrivateData;
class QDESIGNER_WIDGET_EXPORT wcButton : public QWidget {
Q_OBJECT
public:
wcButton(QWidget *parent = Q_NULLPTR);
Q_PROPERTY(QString text READ getButtonText WRITE setButtonText)
void setButtonText(QString text);
QString getButtonText();
protected:
void enterEvent(QEvent* e);//鼠标进入界面
void leaveEvent(QEvent* e);//鼠标离开界面
void mousePressEvent(QMouseEvent *e)override;
void mouseReleaseEvent(QMouseEvent *e)override;
void mouseMoveEvent(QMouseEvent *e)override;
void paintEvent(QPaintEvent *p)override;
QSize sizeHint()const override;
QSize minimumSizeHint() const override;
private:
void drawHighLightBkg(QPainter* painter);
void drawBkg(QPainter* painter);
void drawPressBkg(QPainter* painter);
void drawUsuallyButton(QPainter* painter);
void drawPressButton(QPainter* painter);
void drawText(QPainter* painter);
Q_SIGNALS:
void clicked();
private:
bool _leftButtonPress = false;//左键按下
bool _mouseOn = false;//鼠标在界面上
wcButtonPrivateData* _buttonData = nullptr;
};
#include "wcButton.h"
#include <QPainter>
#include <QMouseEvent>
//私有数据类
class wcButtonPrivateData {
public:
wcButtonPrivateData();
~wcButtonPrivateData();
void setButtonText(QString text) {
_text = text;
}
QString&getButtonText() {
return _text;
}
QFont&getFont() {
return _font;
}
QColor&getStartColor() {
return _startColor;
}
QColor&getEndColor() {
return _endColor;
}
QColor&getGraphicColor() {
return _graphicColor;
}
private:
QString _text = QStringLiteral("测试");
QFont _font;
QColor _startColor = QColor(15, 35, 53);//按钮渐变色中的开始颜色
QColor _endColor = QColor(91, 83, 253);//按钮渐变色中的结束颜色
QColor _graphicColor = QColor(31, 124, 250);//绘制的图形的颜色
};
wcButtonPrivateData::wcButtonPrivateData() {
_font.setFamily(QStringLiteral("微软雅黑"));
_font.setPointSize(10);
}
wcButtonPrivateData::~wcButtonPrivateData() {
}
//
wcButton::wcButton(QWidget *parent)
: QWidget(parent) {
_buttonData = new wcButtonPrivateData;
}
void wcButton::setButtonText(QString text) {
_buttonData->setButtonText(text);
}
QString wcButton::getButtonText() {
return _buttonData->getButtonText();
}
void wcButton::enterEvent(QEvent* e) {
_mouseOn = true;
this->update();
}
void wcButton::leaveEvent(QEvent* e) {
_mouseOn = false;
this->update();
}
void wcButton::mousePressEvent(QMouseEvent *e) {
if (e->button() & Qt::LeftButton) {
_leftButtonPress = true;
this->update();
}
}
void wcButton::mouseReleaseEvent(QMouseEvent *e) {
if (e->button() & Qt::LeftButton) {
_leftButtonPress = false;
emit clicked();
this->update();
}
}
void wcButton::mouseMoveEvent(QMouseEvent *e) {
}
void wcButton::paintEvent(QPaintEvent *p) {
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
drawBkg(&painter);
drawPressBkg(&painter);
drawHighLightBkg(&painter);
drawText(&painter);
}
QSize wcButton::sizeHint() const {
return QSize(80, 30);
}
QSize wcButton::minimumSizeHint() const {
return QSize(80, 30);
}
void wcButton::drawHighLightBkg(QPainter* painter) {
painter->save();
if (_mouseOn && !_leftButtonPress) {//当鼠标在界面上时,高亮显示背景
QLinearGradient radialGradient(QPoint(0, 0), QPoint(0, height()));
radialGradient.setColorAt(1.0, _buttonData->getStartColor());
radialGradient.setColorAt(0.0, _buttonData->getEndColor());
painter->setPen(Qt::NoPen);
painter->setBrush(radialGradient);
painter->drawRoundedRect(0, 0, width(), height(), 5.0, 5.0);
} else {
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::NoBrush);
painter->drawRoundedRect(0, 0, width(), height(), 5.0, 5.0);
}
painter->restore();
}
void wcButton::drawBkg(QPainter* painter) {
drawUsuallyButton(painter);
}
void wcButton::drawPressBkg(QPainter* painter) {
painter->save();
if (!_leftButtonPress) {
drawUsuallyButton(painter);
} else {//当鼠标左键按下时
drawPressButton(painter);
}
painter->restore();
}
void wcButton::drawUsuallyButton(QPainter* painter) {
painter->save();
QPen pen;
pen.setWidth(2);
pen.setColor(_buttonData->getGraphicColor());
painter->setPen(pen);
painter->setBrush(_buttonData->getStartColor());
painter->drawRoundedRect(1, 1, width() - 2, height() - 2, 5.0, 5.0);
painter->restore();
}
void wcButton::drawPressButton(QPainter* painter) {
painter->save();
QLinearGradient radialGradient(QPoint(0, 0), QPoint(0, height()));
radialGradient.setColorAt(0.0, _buttonData->getStartColor());
radialGradient.setColorAt(1.0, _buttonData->getEndColor());
painter->setPen(Qt::NoPen);
painter->setBrush(radialGradient);
painter->drawRoundedRect(0, 0, width(), height(), 5.0, 5.0);
painter->restore();
}
void wcButton::drawText(QPainter* painter) {
painter->save();
QPen pen;
pen.setWidth(2);
pen.setColor(_buttonData->getGraphicColor());
QRect rect(0, 0, width(), height());
painter->setPen(Qt::NoPen);
painter->drawRoundedRect(rect, 5.0, 5.0);
pen.setColor(Qt::white);
painter->setPen(pen);
painter->setFont(_buttonData->getFont());
if (_leftButtonPress) {
rect.setLeft(rect.left() + 2);
rect.setTop(rect.top() + 2);
}
painter->drawText(rect, Qt::AlignHCenter | Qt::AlignVCenter, _buttonData->getButtonText());
#if 0
QFontMetrics metrice(_buttonData->getFont());
int textW = metrice.width(text);
int textH = metrice.height();
painter->drawPixmap(rect.center().x() - _pixmap.width() / 2, 2, _pixmap);
#endif
painter->restore();
}
2.定义到处的控件类型
#pragma once
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class wcButtonPlugin : public QObject, public QDesignerCustomWidgetInterface {
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface" FILE "wcbuttonplugin.json")
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
wcButtonPlugin(QObject *parent = Q_NULLPTR);
bool isContainer() const;
bool isInitialized() const;
QIcon icon() const;
QString domXml() const;
QString group() const;
QString includeFile() const;
QString name() const;
QString toolTip() const;
QString whatsThis() const;
QWidget *createWidget(QWidget *parent);
void initialize(QDesignerFormEditorInterface *core);
private:
bool initialized;
};
#include "wcButton.h"
#include "wcButtonPlugin.h"
#include <QtCore/QtPlugin>
wcButtonPlugin::wcButtonPlugin(QObject *parent)
: QObject(parent) {
initialized = false;
}
void wcButtonPlugin::initialize(QDesignerFormEditorInterface * /*core*/) {
if (initialized)
return;
initialized = true;
}
bool wcButtonPlugin::isInitialized() const {
return initialized;
}
QWidget *wcButtonPlugin::createWidget(QWidget *parent) {
return new wcButton(parent);
}
QString wcButtonPlugin::name() const {
return "wcButton";
}
QString wcButtonPlugin::group() const {//所在的组名
return "Buttons";
}
QIcon wcButtonPlugin::icon() const {//显示的图标
return QIcon(QLatin1String(":/Res/Resources/icon/1.png"));
}
QString wcButtonPlugin::toolTip() const {
return QString();
}
QString wcButtonPlugin::whatsThis() const {
return QString();
}
bool wcButtonPlugin::isContainer() const {
return false;
}
QString wcButtonPlugin::domXml() const {//设置初始的大小
return "<widget class=\"wcButton\" name=\"wcButton\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>80</width>\n"
" <height>40</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n";
}
QString wcButtonPlugin::includeFile() const {
return "wcButton.h";
}
3.发不到Qt Designer中
3.1 新建文本文件,添加一下内容
#include "wcButton.h"
3.2 新建一个批处理文件,添加一下内容:
@echo off
title 安装插件
rem 复制DLL
xcopy *.dll C:\Qt\Qt5.10.0\5.10.0\msvc2015_64\plugins\designer\*.dll /Y
rem 复制lib
xcopy *.lib C:\Qt\Qt5.10.0\5.10.0\msvc2015_64\lib\*.lib /Y
rem 复制h
xcopy *.h C:\Qt\Qt5.10.0\5.10.0\msvc2015_64\include\QtWidgets\*.h /Y
copy wcButton C:\Qt\Qt5.10.0\5.10.0\msvc2015_64\include\QtWidgets\wcButton /Y
pause
3.3 把对应的文件放到统一的一个文件夹中,点击运行.bat文件即可
源码下载
aaa