Qt第十章设计师

Designer设计师的使用

本文图片资源已上传

1.创建带UI文件的项目

2.UI设计器使用

在这里插入图片描述
下面的+号能编辑信号与槽,如果没显示,打开视图>视图>信号和槽编辑器
在这里插入图片描述
也可以右键控件,转到槽,写自定义槽

void Widget::on_pushButton_pressed()
{
    showMaximized();
    ui->pushButton->raise(); // 放到前面
}

void Widget::on_pushButton_2_pressed()
{
    showNormal();
    ui->pushButton_2->raise();
}

3.自定义控件

1. 通过控件提升,可以实现自定义控件

先写一个自己的UI控件

#include "MyWidget.h"
#include "ui_MyWidget.h"

MyWidget::MyWidget(QWidget* parent)
    : QWidget(parent)
    , ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    state = false;
    ui->label->setPixmap(tr(":/images/check_off.png"));
}

MyWidget::~MyWidget()
{
    delete ui;
}

void MyWidget::mousePressEvent(QMouseEvent* event)
{
    if (!state)
        ui->label->setPixmap(tr(":/images/check_off.png"));
    else
        ui->label->setPixmap(tr(":/images/check_on.png"));
    state = !state;
}

然后在原来的widget.ui上面添加一个widget,对这个widget右键,控件提升
在这里插入图片描述
提升后运行效果如下
在这里插入图片描述

2. 新建自定义控件

1. 新建项目
  1. 新建设计师自定义控件项目在这里插入图片描述

  2. 给项目取个名字,我这里叫SWaterProgressBarPlugn

  3. 一直点击下一步,直到如下界面,添加一个类名 SWaterProgressBar

在这里插入图片描述

  1. 然后一直下一步,直到完成

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 添加代码
  1. 创建SWaterProgressBar.h头文件并添加如下代码。
#ifndef _SWATERPROGRESSBAR_H_
#define _SWATERPROGRESSBAR_H_

#include <QWidget>

struct SWaterProgressBarPrivate
{
	int value = 0;			//当前值
	qreal yOffset = 0;		//波浪偏移
	int minValue = 0;
	int maxValue = 100;
	QString text;
	bool textVisible = true;
	int minRadius = 0;		//qMin(width(),height())/2
	qreal scale = 0.;		//value 在最大值和最小值中的占比
};

class Q_DECL_EXPORT  SWaterProgressBar : public QWidget
{
	Q_OBJECT
public:
	explicit SWaterProgressBar(QWidget* parent = nullptr);

	int minimum() const;
	int maximum() const;

	int value() const;

	virtual QString text() const;
	void setTextVisible(bool visible);
	bool isTextVisible() const;

protected:
	void resizeEvent(QResizeEvent* ev)override;
	void paintEvent(QPaintEvent* ev)override;
	void drawBackground(QPainter* painter);
	void drawText(QPainter* painter);
	void drawWater(QPainter* painter);
public Q_SLOTS:
	void updaterWater();

	void reset();
	void setRange(int minimum, int maximum);
	void setMinimum(int minimum);
	void setMaximum(int maximum);
	void setValue(int value);
Q_SIGNALS:
	void valueChanged(int value);
private:
	QScopedPointer<SWaterProgressBarPrivate> d;
};

#endif // !_SWATERPROGRESSBAR_H_

  1. 在SWaterProgressBar.cpp中添加如下代码
#include "SWaterProgressBar.h"
#include <QPainter>
#include <QPainterPath>
#include <QTimer>


SWaterProgressBar::SWaterProgressBar(QWidget* parent)
	:QWidget(parent)
{
	d.reset(new SWaterProgressBarPrivate);
	resize(100, 100);

    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &SWaterProgressBar::updaterWater);
    timer->start(30);//定时30毫秒
}

void SWaterProgressBar::resizeEvent(QResizeEvent* ev)
{
    d->minRadius = qMin(width(), height()) / 2;
}

void SWaterProgressBar::paintEvent(QPaintEvent* ev)
{
	Q_UNUSED(ev);
    //d->value 在range内所占比例
    d->scale = (qreal)(qAbs(d->value - d->minValue)) / (qAbs(d->maxValue - d->minValue));
	QPainter painter(this);
	painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);	//设置抗锯齿
	painter.translate(width() / 2, height() / 2);	//设置坐标原点为控件中心
	//painter.scale(side / 200.0, side / 200.0);//设置坐标系拉伸为200*200
	drawBackground(&painter);
    drawWater(&painter);
	drawText(&painter);
 
}

void SWaterProgressBar::drawBackground(QPainter* painter)
{
	painter->save();

	painter->setPen(Qt::NoPen);
	painter->setBrush(QColor(40, 40, 40));
	QRect rect(-d->minRadius, -d->minRadius, d->minRadius * 2, d->minRadius * 2);
	painter->drawEllipse(rect);

	painter->restore();
}

void SWaterProgressBar::drawText(QPainter* painter)
{
    if (d->textVisible)
    {
        painter->save();
        d->text = QString("%1%").arg(d->scale * 100,2,'f', 1);
        //设置字体大小
        //QFont font = painter->font();
        //font.setPixelSize(30);
        //painter->setFont(font);
        //设置画笔
        painter->setPen(QPen(Qt::white, 4));
        //绘制文本
        QRect r(-d->minRadius, -d->minRadius, d->minRadius * 2, d->minRadius * 2);
        painter->drawText(r, Qt::AlignCenter, d->text);

        painter->restore();
    }
}

void SWaterProgressBar::drawWater(QPainter* painter)
{
    if (d->value == d->minValue) //没波浪,不用画
    {
        return;
    }
    else if (d->value == d->maxValue) //波浪满,直接画圆
    {
        painter->save();
        painter->setPen(Qt::NoPen);
        painter->setBrush(QBrush(QColor(100, 180, 250, 230)));
        painter->drawEllipse(QRect(-d->minRadius, -d->minRadius, d->minRadius * 2, d->minRadius * 2));
        painter->restore();
    }
    else//画波浪
    {
        int side = qMin(width(), height());
        int height = side/2 - d->scale * side;  //100/2 - 0.5 * 100
        painter->save();
        QPainterPath wavePath; //波浪区域
        QPainterPath wavePath2; //波浪区域
      
        //1.8 角速度
        //4   振幅
        //height y轴相对远点偏移
        //d->yOffset x=0时的相位;反映在坐标系上则为图像的左右移动。
        //x * M_PI / 180  把x当做角度,转成弧度
        wavePath.moveTo(-d->minRadius, d->minRadius);       //第一点坐标为(0,height);
        for (int x = -d->minRadius; x <= d->minRadius; x++)  //x从0~w的值而改变,从而得到正弦曲线
        {
            double waveY = 4 * qSin(1.8 * (x * M_PI / 180 + d->yOffset)) + height;// waveY随着x的值改变而改变,从而得到正弦曲线
            wavePath.lineTo(x, waveY);   //从上一个绘制点画一条线到(x,waveY);
        }
        wavePath.lineTo(d->minRadius, d->minRadius); //右下角,坐标(width, height),移动到右下角结束点,整体形成一个闭合路径

        wavePath2.moveTo(-d->minRadius, d->minRadius);//第一点坐标为(0,height);
        for (int x = -d->minRadius; x <= d->minRadius; x++)  //x从0~w的值而改变,从而得到正弦曲线
        {
           double waveY = 4 * qSin(1.8 * (x * M_PI / 180 + d->yOffset + 2)) + height;// waveY随着x的值改变而改变,从而得到正弦曲线
           wavePath2.lineTo(x, waveY);   //从上一个绘制点画一条线到(x,waveY);
        }
        wavePath2.lineTo(d->minRadius, d->minRadius); //右下角,坐标(width, height),移动到右下角结束点,整体形成一个闭合路径

        QPainterPath bigPath;
        bigPath.addEllipse(QRect(-d->minRadius, -d->minRadius, d->minRadius * 2, d->minRadius * 2));
        wavePath = bigPath.intersected(wavePath);
        wavePath2 = bigPath.intersected(wavePath2);

        painter->setPen(Qt::NoPen);
        painter->setBrush(QBrush(QColor(100, 184, 255, 80)));
        painter->drawPath(wavePath);      //绘制路径
        painter->setBrush(QBrush(QColor(100, 180, 250, 230)));
        painter->drawPath(wavePath2);      //绘制路径
        painter->restore();
    }
}

int SWaterProgressBar::minimum() const
{
    return d->minValue;
}

int SWaterProgressBar::maximum() const
{
    return d->maxValue;
}

int SWaterProgressBar::value() const
{
    return d->value;
}

QString SWaterProgressBar::text() const
{
    return d->text;
}

void SWaterProgressBar::setTextVisible(bool visible)
{
    d->textVisible = visible;
}

bool SWaterProgressBar::isTextVisible() const
{
    return d->textVisible;
}

void SWaterProgressBar::reset()
{
    d->minValue = 0;
    d->maxValue = 100;
}
void SWaterProgressBar::setRange(int minimum, int maximum)
{
    d->minValue = minimum;
    d->maxValue = maximum;
    d->value = minimum;
}
void SWaterProgressBar::setMinimum(int minimum)
{
    d->minValue = minimum;
    d->value = minimum;
}
void SWaterProgressBar::setMaximum(int maximum)
{
    d->maxValue = maximum;
}
void SWaterProgressBar::setValue(int value)
{
    if (value != d->value)
    {
        d->value = value;
        emit valueChanged(value);
    }   
}


void SWaterProgressBar::updaterWater()
{
    d->yOffset += 0.15;//波浪偏移
    if (d->yOffset >= 360)
        d->yOffset = 0;
    update();
}

  1. 添加图标资源

在这里插入图片描述

3.生成动态库
  • 构建套件 这里选择MSVC 64bit Release

    • Release

至此,自定义控件dll生成完毕!

2.DLL文件使用
1. QtCreator使用DLL

Qt6自带的QtCreator是64bit,所以要在QC中使用插件,只能使用64bit的DLL文件,将64bit/Release版本的.dll文件复制到QtCreator的路径下,然后打开Qt就可以看到控件了(无需将64bit/Debug版本的放入,QtCreator只支持64bit/Release版本的.dll文件)。

PS:出现如下警告,运行程序窗口不会显示出来

MSVC 如果在Debug模式下,使用了Release模式编译的DLL,则会警告:QWidget: Must construct a QApplication before a QWidget

  1. 复制64bit/Release版本的 swaterprogressbarplugin.dll\Qt\Tools\QtCreator\bin\plugins\designer

在这里插入图片描述

  1. 然后重新打开QC,就可以看到自定义控件,拖到Ui界面也正常显示
    在这里插入图片描述

  2. 如果将release和debug的DLL文件同时放入,debug的DLL文件不能正常加载。点击 工具->From Editor->About Qt Designer Plugins 可以查看加载的插件以及失败的插件和不能加载的原因

  3. 此时,只是在UI界面能够把控件拖出来,还不能运行,因为没有配置头文件和库文件。

    • 将swaterprogressbarplugind.h放入项目的源码目录

    • 对应的构建也要是release构建,debug是不行的
      在这里插入图片描述

    • 将swaterprogressbarplugind.lib和swaterprogressbarplugind.dll文件放入生成的exe同级目录。

在这里插入图片描述

  • CMakeLists.txt配置库

    target_link_libraries(designer PRIVATE Qt${QT_VERSION_MAJOR}::Widgets swaterprogressbarplugin)
    

    即在原来的targetlink后添加你的库 swaterprogressbarplugin

Ok!完美运行

在这里插入图片描述

注意要查看QCreator当前用的构建套件,点帮助>about QtCreator

3.
我现在是6.6.3,执行上述添加自定义控件的时候,项目构建套件要设置成6.6.3 MSVC
在这里插入图片描述

4.UI设计师原理

  • QT 生成的.ui文件用本身的Qc不可以修改,但可以用记事本打开修改,是xml语法写的,如果不熟悉不要改,否则会报错
  • Qt通过moc rcc 把 QT文件转换成纯C++语言,在G:\qtproject\designer\build\Desktop_Qt_6_6_3_MSVC2019_64bit-Release\designer_autogen\EWIEGA46WW 文件夹里可以查看到
    *
  • uic编译的文件在 G:\qtproject\designer\build\Desktop_Qt_6_6_3_MSVC2019_64bit-Release\designer_autogen\include文件夹里

5.用UI文件生成头文件

打开QT自带的命令窗口在这里插入图片描述
定位到你的ui文件所在文件夹
输入命令uic xxx.ui -o ui_xxx.h
在这里插入图片描述
就会在当前文件夹中生成.h头文件

6.使用ui_widget.h

然后和正常生成的UI一样使用就行了

  • 11
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yerennuo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值