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. 新建项目
-
新建设计师自定义控件项目
-
给项目取个名字,我这里叫SWaterProgressBarPlugn
-
一直点击下一步,直到如下界面,添加一个类名 SWaterProgressBar
- 然后一直下一步,直到完成
2. 添加代码
- 创建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_
- 在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();
}
- 添加图标资源
3.生成动态库
-
构建套件 这里选择MSVC 64bit Release
- 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
- 复制64bit/Release版本的 swaterprogressbarplugin.dll 到
\Qt\Tools\QtCreator\bin\plugins\designer
-
然后重新打开QC,就可以看到自定义控件,拖到Ui界面也正常显示
-
如果将release和debug的DLL文件同时放入,debug的DLL文件不能正常加载。点击 工具->From Editor->About Qt Designer Plugins 可以查看加载的插件以及失败的插件和不能加载的原因
-
此时,只是在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
我现在是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一样使用就行了
原文地址:https://blog.csdn.net/yerennuo/article/details/139918779
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!