今天来给大家分享一下QT自定义widget控件及其使用,当ui设计器提供的界面不满足实际需求时,可以从QWidget继承自定义的界面组件。有两种方法一种是提升法,另一种是ui设计器自定义界面组件widget组件。我们本次先说提升法。
通过这个简单的例子说明提升法
在这个窗体中,有一个label控件,一个horizontalSlider控件,以及一个自定义的电池控件。
1 为了设计这个电池控件,首先设计一个自定义的widget组件。
为此,设计一个从Qwidget中继承的类QmyBattery。创建C++类,点击QT Creator的File ->new file or project->C++ class,设置类名称为QmyBattery
以下是Qmybattrey.h中的代码:
#ifndef QMYBATTERY_H
#define QMYBATTERY_H
#include <QWidget>
#include <Qcolor>
#include <QRect>
class QmyBattery : public QWidget
{
Q_OBJECT
private:
//背景颜色
QColor mColorBack=Qt::white;
//电池边框颜色
QColor mColorBorder=Qt::black;
//电池柱颜色
QColor mColorPower=Qt::green;
//电池短缺颜色
QColor mColorWarning=Qt::red;
//电量0-100
int mPowerLevel=60;
//电量低警示阈值
int myWarnLevrl=20;
protected:
//后面的宏是为了声明对一个虚函数定义的方法
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
public:
explicit QmyBattery(QWidget *parent = nullptr);
//设置当前电池电量
void setPowerLevel(int pow);
int powerLevel();
//设置电池电量低阈值
void setWarnLevel(int warn);
int warnLevel();
//缺省大小
QSize sizeHint();
signals:
void powerLevelChanged();
public slots:
};
#endif // QMYBATTERY_H
下面是QmyBattery.cpp中的代码:
#include "qmybattery.h"
#include <QPainter>
#include <QPen>
//界面的绘制
void QmyBattery::paintEvent(QPaintEvent *event)
{
//避免编译错误
Q_UNUSED(event);
QPainter painter(this);
QRect rect(0,0,width(),height());
//设置当前图形视图窗口
painter.setViewport(rect);
painter.setWindow(0,0,120,50);
//抗锯齿的效果
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::TextAntialiasing);
QPen pen;
pen.setWidth(2);
pen.setColor(mColorBorder);
pen.setStyle(Qt::SolidLine);
pen.setCapStyle(Qt::FlatCap);
pen.setJoinStyle(Qt::BevelJoin);
painter.setPen(pen);
QBrush brush;
brush.setColor(mColorBack);
brush.setStyle(Qt::SolidPattern);
painter.setBrush(brush);
rect.setRect(1,1,109,48);
painter.drawRect(rect);
brush.setColor(mColorBorder);
painter.setBrush(brush);
//电池头
rect.setRect(110,15,10,20);
painter.drawRect(rect);
if(mPowerLevel>myWarnLevrl){
brush.setColor(mColorPower);
pen.setColor(mColorPower);
}else{
brush.setColor(mColorWarning);
pen.setColor(mColorWarning);
}
painter.setBrush(brush);
painter.setPen(pen);
if(mPowerLevel>0){
rect.setRect(5,5,mPowerLevel,40);
painter.drawRect(rect);
}
QFontMetrics textsize(this->font());
QString powStr=QString::asprintf("%d%%",mPowerLevel);
QRect textRect=textsize.boundingRect(powStr);
painter.setFont(this->font());
pen.setColor(mColorBorder);
painter.setPen(pen);
painter.drawText(55-textRect.width()/2,23+textRect.height()/2,powStr);
}
void QmyBattery::setPowerLevel(int pow)
{
mPowerLevel=pow;
emit powerLevelChanged();
repaint();
}
int QmyBattery::powerLevel()
{
return mPowerLevel;
}
void QmyBattery::setWarnLevel(int warn)
{
myWarnLevrl=warn;
repaint();
}
int QmyBattery::warnLevel()
{
return myWarnLevrl;
}
QSize QmyBattery::sizeHint()
{
int H=this->height();
int W=H*12/5;
QSize size(W,H);
return size;
}
QmyBattery::QmyBattery(QWidget *parent) : QWidget(parent)
{
}
2 实现QmyBattery类之后,若用代码创建QmyBattery类对象,可以参考我的博文纯代码创建Qtpushbutton,我们在这用提升法实现
,首先在ui设计器中选择widget控件,鼠标右键点击提升为
点击添加
点击提升
3虽然界面上放置的QWidget组件提升为QmyBattery类,但是这个组件在建立信号是没有QmyBattery类的powerLevelChanged(int)信号,无法采用可视化实现信号的槽函数。
所以在主窗口放置一个label 和horizontalSlider控件,滑动标尺改变数值时,设置为当前电量值
void Dialog::on_horizontalSlider_valueChanged(int value)
{
ui->widget->setPowerLevel(value);
QString str=QStringLiteral("DL: ")+QString::asprintf("%d %%",value);
ui->label->setText(str);
}