自定义checkbox
前提
搞个项目。使得checkbox再选中的同时可以显示波形的名称和颜色,同时控制波形的显示和隐藏,Qt本身的checkbox显然不可以显示颜色,因此,就想自己写一个checkbox。
新建一个设计师项目
见其他博主如MelyLenient: 一篇学会QT使用–设计师自定义控件(QT自定义控件)(一)
头文件内容
#ifndef TCHECKBOX_H
#define TCHECKBOX_H
#include <QWidget>
#include <QObject>
#include <QMenu>
#if defined T_CHECKBOX
# define Q_EXPORT Q_DECL_EXPORT
#else
# define Q_EXPORT
#endif
class Q_EXPORT TCheckBox : public QWidget
{
Q_OBJECT
//设置属性
Q_PROPERTY(bool isChecked READ getIsChecked WRITE setIsChecked)
Q_PROPERTY(QString text READ getIsText WRITE setIsText)
Q_PROPERTY(QColor lineColor READ getlineColor WRITE setlineColor)
Q_PROPERTY(QColor hookColor READ gethookColor WRITE sethookColor)
Q_PROPERTY(QColor boxColor READ getboxColor WRITE setboxColor)
Q_PROPERTY(QColor textColor READ gettextColor WRITE settextColor)
Q_PROPERTY(QFont textFont READ getIsFont WRITE setIsFont)
public:
explicit TCheckBox(QWidget *parent = nullptr);
bool getIsChecked() const; //设置选中状态
void setIsChecked(const bool &isChecked); //获取选中状态
void setIsText(const QString &text); //设置文字
QString getIsText() const;//获取文字
void setlineColor(const QColor &lineColor); //设置线颜色
QColor getlineColor() const; //获取线颜色
void sethookColor(const QColor &hookColor); //设置对勾颜色
QColor gethookColor() const; //获取对勾颜色
void setboxColor(const QColor &boxColor); //设置框颜色
QColor getboxColor() const; //获取框颜色
void settextColor(const QColor &textColor); //设置文本颜色
QColor gettextColor() const; //获取文本颜色
void setIsFont(const QFont &textFont); //设置文本字体
QFont getIsFont() const; //获取文本字体
public Q_SLOTS:
void onClicked();
protected:
virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void drawBorder(QPainter *painter); //绘制边框
void drawHook(QPainter *painter); //绘制选中
void drawLine(QPainter *painter); //绘制line
void drawText(QPainter *painter); //绘制文本
private:
QPainter *painter; //定义一个画家
QRectF boxRect; //box主体区域
int borderWidth; //设置边框大小
double boxWidth; //设置box边框宽度
QString text; //设置文字
QColor lineColor; //设置线颜色
QColor hookColor; //设置对勾颜色
QColor boxColor; //设置框颜色
QColor textColor; //设置文本颜色
QFont textFont; //设置文本字体
bool isChecked ; //设置状态
//定义菜单
QMenu *RightButtonMenu; //右键菜单
QAction *setText; //设置文字
QAction *setColor;//设置颜色
QAction *quitShot;//退出
private Q_SLOTS:
void addMenu(const QPoint pos); //添加右键菜单
void changedText(); //改变文字
void changedColor(); //改变线的颜色
Q_SIGNALS:
void statechanged(bool isChecked);
void pointPos(const QPoint &pos);
};
#endif // TCHECKBOX_H
头文件内容分析
首先,宏定义要配合类使用,当在pro文件中定义了 T_CHECKBOX 时 就定义 # define Q_EXPORT Q_DECL_EXPORT。这个宏定义在导出库时使用,因此要在pro文件中添加DEFINES +=T_CHECKBOX
#if defined T_CHECKBOX
# define Q_EXPORT Q_DECL_EXPORT
#else
# define Q_EXPORT
#endif
class Q_EXPORT TCheckBox : public QWidget
{
其次,Q_PROPERTY(xx READ xxx WRITE xxx)是设置的属性,在后面使用时可以直接在QtCreator的designer中显示出来。
//设置属性
Q_PROPERTY(bool isChecked READ getIsChecked WRITE setIsChecked)
Q_PROPERTY(QString text READ getIsText WRITE setIsText)
Q_PROPERTY(QColor lineColor READ getlineColor WRITE setlineColor)
Q_PROPERTY(QColor hookColor READ gethookColor WRITE sethookColor)
Q_PROPERTY(QColor boxColor READ getboxColor WRITE setboxColor)
Q_PROPERTY(QColor textColor READ gettextColor WRITE settextColor)
Q_PROPERTY(QFont textFont READ getIsFont WRITE setIsFont)
如图,
然后,设置了一些公共函数,可以直接调用,用来设置/获取checkbox的属性。
public:
explicit TCheckBox(QWidget *parent = nullptr);
bool getIsChecked() const; //设置选中状态
void setIsChecked(const bool &isChecked); //获取选中状态
void setIsText(const QString &text); //设置文字
QString getIsText() const;//获取文字
void setlineColor(const QColor &lineColor); //设置线颜色
QColor getlineColor() const; //获取线颜色
void sethookColor(const QColor &hookColor); //设置对勾颜色
QColor gethookColor() const; //获取对勾颜色
void setboxColor(const QColor &boxColor); //设置框颜色
QColor getboxColor() const; //获取框颜色
void settextColor(const QColor &textColor); //设置文本颜色
QColor gettextColor() const; //获取文本颜色
void setIsFont(const QFont &textFont); //设置文本字体
QFont getIsFont() const; //获取文本字体
最后,设置一些私有函数和成员,以及信号。其中void statechanged(bool isChecked); 用于判断状态改变。
public Q_SLOTS:
void onClicked();
protected:
virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void drawBorder(QPainter *painter); //绘制边框
void drawHook(QPainter *painter); //绘制选中
void drawLine(QPainter *painter); //绘制line
void drawText(QPainter *painter); //绘制文本
private:
QPainter *painter; //定义一个画家
QRectF boxRect; //box主体区域
int borderWidth; //设置边框大小
double boxWidth; //设置box边框宽度
QString text; //设置文字
QColor lineColor; //设置线颜色
QColor hookColor; //设置对勾颜色
QColor boxColor; //设置框颜色
QColor textColor; //设置文本颜色
QFont textFont; //设置文本字体
bool isChecked ; //设置状态
//定义菜单
QMenu *RightButtonMenu; //右键菜单
QAction *setText; //设置文字
QAction *setColor;//设置颜色
QAction *quitShot;//退出
private Q_SLOTS:
void addMenu(const QPoint pos); //添加右键菜单
void changedText(); //改变文字
void changedColor(); //改变线的颜色
Q_SIGNALS:
void statechanged(bool isChecked); //用于判断状态改变
void pointPos(const QPoint &pos);
cpp文件内容
#include <QtGlobal>
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# pragma execution_character_set("utf-8") //设置中文不乱码
#endif
#if (QT_VERSION <= QT_VERSION_CHECK(6,0,0))
#include <QTextCodec>
#endif
#include "tcheckbox.h"
#include <QDebug>
#include <QPainter>
#include <QStyle>
#include <QStyleOption>
#include <QMouseEvent>
#include <QColorDialog>
#include <QInputDialog>
#include <QLineEdit>
TCheckBox::TCheckBox(QWidget *parent)
: QWidget{parent}
,borderWidth(0) //默认设置边框大小为0
,boxWidth(13) //默认值为15
,text("TCheckBox")
,lineColor(Qt::black)//默认显示黑色
,hookColor(Qt::white)//默认显示白色
,boxColor(Qt::black)//默认设置黑色
,textColor(Qt::black)//默认设置黑色
,textFont(QFont("Arial")) //默认设置字体
,isChecked(false)//默认未选中
,RightButtonMenu(new QMenu(this))//右键菜单
,setText(new QAction(tr("设置文字"), this))
,setColor(new QAction(tr("设置颜色"), this))
,quitShot(new QAction(tr("退出"), this))
{
#if (QT_VERSION <= QT_VERSION_CHECK(6,0,0))
QTextCodec *codec = QTextCodec::codecForName("utf-8");
QTextCodec::setCodecForLocale(codec);
#endif
connect(this, &TCheckBox::statechanged, this, &TCheckBox::onClicked);
connect(this,&TCheckBox::pointPos,this,&TCheckBox::addMenu);
connect(setText,&QAction::triggered,this,&TCheckBox::changedText);
connect(setColor,&QAction::triggered,this,&TCheckBox::changedColor);
connect(setColor,&QAction::triggered,this,[=](){
RightButtonMenu->close();
});
}
void TCheckBox::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
//绘制边框
drawBorder(&painter);
//绘制对勾
if(isChecked){
drawHook(&painter);
}
//绘制直线
drawLine(&painter);
//绘制文字
drawText(&painter);
}
void TCheckBox::mousePressEvent(QMouseEvent *event)
{
if(event->button()== Qt::LeftButton)
{
isChecked = !isChecked;
emit statechanged(isChecked);
}
else if(event->button()== Qt::RightButton)
{
emit pointPos(event->pos());
}
else
;
}
void TCheckBox::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
}
void TCheckBox::drawBorder(QPainter *painter)
{
painter->save();
QPen pen;
pen.setWidth(1);//设置线宽
//pen.setColor(Qt::red); //设置颜色
pen.setColor(boxColor); //rgb设置颜色
pen.setStyle(Qt::SolidLine);//设置线样式
painter->setPen(pen);
int radiusWidth= boxWidth/8;
//绘制box边框
QPointF topLeft(borderWidth, borderWidth);
QPointF bottomRight(boxWidth, boxWidth);
boxRect = QRectF(topLeft, bottomRight);
painter->setBrush(Qt::white);
painter->drawRoundedRect(boxRect, radiusWidth, radiusWidth);
painter->restore();
}
void TCheckBox::drawHook(QPainter *painter)
{
painter->save();
QPen pen;
pen.setWidth(1);//设置线宽
pen.setColor(boxColor); //rgb设置颜色
pen.setStyle(Qt::SolidLine);//设置线样式
painter->setPen(pen);
double radiusWidth= boxWidth/8;
QBrush brush; //画刷。填充几何图形的调色板,由颜色和填充风格组成
brush.setColor(boxColor);
brush.setStyle(Qt::SolidPattern);
painter->setBrush(brush);
painter->drawRoundedRect(boxRect, radiusWidth, radiusWidth);
QPen Linepen;
Linepen.setWidth(boxWidth/4);//设置线宽
Linepen.setColor(hookColor); //rgb设置颜色
Linepen.setStyle(Qt::SolidLine);//设置线样式
painter->setPen(Linepen);
//绘制box边框
QPointF firstPonit(boxWidth*3/16,boxWidth/2);
QPointF secondPonit(boxWidth*0.4,boxWidth*11/16);
QPointF thirdPonit(boxWidth*13/16,boxWidth*2/8);
QLineF firstLine(firstPonit,secondPonit);
QLineF secondLine(secondPonit,thirdPonit);
painter->drawLine(firstLine);
painter->drawLine(secondLine);
painter->restore();
}
void TCheckBox::drawLine(QPainter *painter)
{
painter->save();
QPen pen;
pen.setWidth(boxWidth/3);//设置线宽
pen.setColor(lineColor); //设置线颜色
pen.setStyle(Qt::SolidLine);//设置线样式
painter->setPen(pen);
//绘制box边框
QPointF firstPonit(boxWidth*1.5,boxWidth/2);
QPointF secondPonit(boxWidth*3.0,boxWidth/2);
QLineF Line(firstPonit,secondPonit);
painter->drawLine(Line);
painter->restore();
}
void TCheckBox::drawText(QPainter *painter)
{
painter->save();
QPen pen;
pen.setColor(textColor); //设置线颜色
pen.setStyle(Qt::SolidLine);//设置线样式
painter->setPen(pen);
//绘制box边框
QPointF topLeft(boxWidth*3.5, boxWidth);
//设置字体
painter->setFont(textFont);
//画字体
painter->drawText(topLeft, text);
painter->restore();
}
void TCheckBox::addMenu(const QPoint pos)
{
Q_UNUSED(pos);
RightButtonMenu->clear();
RightButtonMenu->addAction(setColor);
RightButtonMenu->addAction(setText);
RightButtonMenu->addSeparator(); //分割线
RightButtonMenu->addAction(quitShot);
RightButtonMenu->exec(QCursor::pos()); //在当前鼠标处堵住
}
void TCheckBox::changedText()
{
bool ok=false;
QInputDialog isgetText = new QInputDialog(this);
isgetText.setOkButtonText(tr("确认"));
isgetText.setCancelButtonText(tr("取消"));
QString newtext = isgetText.getText(this, tr("修改文本名称")
,tr("请输入新文本名称")
,QLineEdit::Normal //正常文字输入
,this->text
,&ok);
if (ok && !newtext.isEmpty())
{
this->setIsText(newtext);
}
}
void TCheckBox::changedColor()
{
QColor color=QColorDialog::getColor(lineColor,this,tr("选择颜色"));
if (color.isValid()) //选择有效
{
this->setlineColor(color);
}
}
void TCheckBox::onClicked()
{
this->update();
}
bool TCheckBox::getIsChecked() const
{
return this->isChecked;
}
void TCheckBox::setIsChecked(const bool &isChecked)
{
if (this->isChecked != isChecked) {
this->isChecked = isChecked;
this->update();
}
}
void TCheckBox::setIsText(const QString &text)
{
if (this->text != text) {
this->text = text;
this->update();
}
}
QString TCheckBox::getIsText() const
{
return this->text;
}
void TCheckBox::setlineColor(const QColor &lineColor)
{
if (this->lineColor != lineColor) {
this->lineColor = lineColor;
this->update();
}
}
QColor TCheckBox::getlineColor() const
{
return this->lineColor;
}
void TCheckBox::sethookColor(const QColor &hookColor)
{
if (this->hookColor != hookColor) {
this->hookColor = hookColor;
this->update();
}
}
QColor TCheckBox::gethookColor() const
{
return this->hookColor;
}
void TCheckBox::setboxColor(const QColor &boxColor)
{
if (this->boxColor != boxColor) {
this->boxColor = boxColor;
this->update();
}
}
QColor TCheckBox::getboxColor() const
{
return this->boxColor;
}
void TCheckBox::settextColor(const QColor &textColor)
{
if (this->textColor != textColor) {
this->textColor = textColor;
this->update();
}
}
QColor TCheckBox::gettextColor() const
{
return this->textColor;
}
void TCheckBox::setIsFont(const QFont &textFont)
{
if (this->textFont != textFont) {
this->textFont = textFont;
this->update();
}
}
QFont TCheckBox::getIsFont() const
{
return this->textFont;
}
效果演示
QtCreator中自定义的checkbox,
测试
完整工程:gitee