QT Widget: 自定义Widget组件及创建和使用动静态库

学习自定义Widget组件,书中的案例:

// 自定义QmyBattery组件
// QmyBattery.c++
#include "qmybattery.h"

QmyBattery::QmyBattery(QWidget *parent) : QWidget(parent)
{

}

/*
 * 1.QPainter的viewport()与window()分别代表着物理坐标与逻辑坐标区域,默认两个区域是重合的,也就是用户指定的rect区域在两者上是同样的大小、位置。
2.setWindow()可以设置你想指定的rect区域,比如rect=(-50,-50,100,100),此时你定义的逻辑区域左上坐标(-50,-50),右下坐标(50,50),大小(100X100),
最重要的是QPainter的drawLine、drawRect或者其它draw操作都是以这个逻辑坐标区域为准来绘制图像的,也就是此时的坐标系原点(0,0)就是(-50,-50)了。
3.SetViewport()设置的是物理坐标区域,它代表着实际显示的区域,切记这只是用户规定的画图区域而不是画图的坐标直接以它为准,你画的图像还是以window()
区域的坐标系为准,最终是要将winodw()逻辑区域映射到viewport()物理区域的,这样以后在使用QPainter进行绘制图形时就可以通过设置这两个方法去放大、
平移图像了,比如保持window()逻辑坐标不变,将viewport()物理坐标区域大小变为之前的2倍,那么实际显示的图像也会自动放大2倍了,至于平移也差不多,我懒得算了。
*/
void QmyBattery::paintEvent(QPaintEvent *event) {
    Q_UNUSED(event)
    QPainter painter(this);// 画家
    qDebug() << "width = "<<width() <<";height = " <<height();
    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 > mWarnLevel) {
        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 power) {
    mPowerLevel = power;
    emit powerLevelChanged(power);
    repaint();
}

int QmyBattery::powerLevel() {
    return mPowerLevel;
}

void QmyBattery::setWarnLevel(int warn) {
    mWarnLevel = warn;
    repaint();
}

int QmyBattery::warnLevel() {
    return mWarnLevel;
}

QSize QmyBattery::siezeHint() {
    int H = this->height();
    int W = H *12/5;
    QSize size(W,H);
    return  size;
}

// QmyBattery.h
#ifndef QMYBATTERY_H
#define QMYBATTERY_H

#include <QWidget>
#include <QPainter>
#include <QDebug>

class QmyBattery : public QWidget
{
    Q_OBJECT
private:
    QColor mColorBack = Qt::white;
    QColor mColorBorder = Qt::black;
    QColor mColorPower = Qt::green;
    QColor mColorWarning = Qt::red;

    int mPowerLevel = 60;
    int mWarnLevel = 20;
protected:
    void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
public:
    explicit QmyBattery(QWidget *parent = nullptr);
    void setPowerLevel(int power);
    int powerLevel();
    void setWarnLevel(int warn);
    int warnLevel();
    QSize siezeHint();

signals:
    void powerLevelChanged(int);

public slots:
};

#endif // QMYBATTERY_H

// 使用 MainWindow.c++
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->battery->setPowerLevel(10);

}

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

void MainWindow::on_slider_valueChanged(int value){
    qDebug() << "value = " <<value;
    ui->battery->setPowerLevel(value);
}

效果图:
在这里插入图片描述
二、创建动态库
1、创建工程
(1)
在这里插入图片描述
(2)
在这里插入图片描述
(3)创建工程名称mySharedLib,选择工程路径。
(4 )添加类名称,我的为QmyBattery选择类型。选择模块为Widgets。动态库选择:
在这里插入图片描述
静态库选择:
在这里插入图片描述
工程新建成功之后,工程目录如下:
在这里插入图片描述
2、自动生成的.pro文件如下:

QT += widgets

TARGET = mySharedLib

TEMPLATE = lib
DEFINES += MYSHAREDLIB_LIBRARY

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    qmybattery.cpp

HEADERS += \
    mySharedLib_global.h \
    qmybattery.h

# Default rules for deployment.
unix {
    target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target

3、添加代码,完成qmybattery.cpp,qmybattery.h文件。

// qmybattery.cpp
#include "qmybattery.h"


QmyBattery::QmyBattery(QWidget *parent) : QWidget(parent)
{

}

/*
 * 1.QPainter的viewport()与window()分别代表着物理坐标与逻辑坐标区域,默认两个区域是重合的,也就是用户指定的rect区域在两者上是同样的大小、位置。
2.setWindow()可以设置你想指定的rect区域,比如rect=(-50,-50,100,100),此时你定义的逻辑区域左上坐标(-50,-50),右下坐标(50,50),大小(100X100),
最重要的是QPainter的drawLine、drawRect或者其它draw操作都是以这个逻辑坐标区域为准来绘制图像的,也就是此时的坐标系原点(0,0)就是(-50,-50)了。
3.SetViewport()设置的是物理坐标区域,它代表着实际显示的区域,切记这只是用户规定的画图区域而不是画图的坐标直接以它为准,你画的图像还是以window()
区域的坐标系为准,最终是要将winodw()逻辑区域映射到viewport()物理区域的,这样以后在使用QPainter进行绘制图形时就可以通过设置这两个方法去放大、
平移图像了,比如保持window()逻辑坐标不变,将viewport()物理坐标区域大小变为之前的2倍,那么实际显示的图像也会自动放大2倍了,至于平移也差不多,我懒得算了。
*/
void QmyBattery::paintEvent(QPaintEvent *event) {
    Q_UNUSED(event)
    QPainter painter(this);// 画家
    qDebug() << "width = "<<width() <<";height = " <<height();
    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 > mWarnLevel) {
        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 power) {
    mPowerLevel = power;
    emit powerLevelChanged(power);
    repaint();
}

int QmyBattery::powerLevel() {
    return mPowerLevel;
}

void QmyBattery::setWarnLevel(int warn) {
    mWarnLevel = warn;
    repaint();
}

int QmyBattery::warnLevel() {
    return mWarnLevel;
}

QSize QmyBattery::siezeHint() {
    int H = this->height();
    int W = H *12/5;
    QSize size(W,H);
    return  size;
}

//  qmybattery.h
#ifndef QMYBATTERY_H
#define QMYBATTERY_H

#include <QWidget>
#include <QPainter>
#include <QDebug>


#include "mySharedLib_global.h"

class MYSHAREDLIB_EXPORT QmyBattery: public QWidget
{
    Q_OBJECT
private:
    QColor mColorBack = Qt::white;
    QColor mColorBorder = Qt::black;
    QColor mColorPower = Qt::green;
    QColor mColorWarning = Qt::red;

    int mPowerLevel = 60;
    int mWarnLevel = 20;
protected:
    void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
public:
    explicit QmyBattery(QWidget *parent = nullptr);
    void setPowerLevel(int power);
    int powerLevel();
    void setWarnLevel(int warn);
    int warnLevel();
    QSize siezeHint();

signals:
    void powerLevelChanged(int);

public slots:
};

#endif // QMYBATTERY_H

3、构建生成so文件。
在这里插入图片描述

在这里插入图片描述
三、使用动态库
1、新建一个工程useShare。
2、把so文件及.h文件拷贝到工程下。注意去掉so后面的1.0.0
在这里插入图片描述

3、添加库
(1)
在这里插入图片描述
(2)
在这里插入图片描述
(3)我是将程序运行到板子里,所以选linux
在这里插入图片描述
添加完成后.pro文件:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

unix:!macx: LIBS += -L$$PWD/./ -lmySharedLib

INCLUDEPATH += $$PWD/.
DEPENDPATH += $$PWD/.

4、添加.h文件。只选择qmybattery.h文件。
在这里插入图片描述
5、加载QmyBatter组件。

// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QmyBattery *battery = new QmyBattery(this);
    battery->setParent(this);
    battery->move(100,100);
    battery->show();
    battery->setPowerLevel(50);
}

MainWindow::~MainWindow()
{
    delete ui;

}


// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "qmybattery.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H


编译运行代码。因为程序在板子里面运行需要把libmySharedLib.so.1.0.0文件push到板子/usr/lib路径下。
静态库的生成和使用 比较简单。不做记录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/420807.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

类加载的基本流程

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;JavaEE &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 类加载 1. 加载2. 验证3. 准备4. 解析5. 初…

maven项目报错Cannot resolve plugin org.apache.maven.plugins:maven-war-plugin:2.2

如果IDEA整合maven没有问题&#xff0c;还是报这个错误&#xff0c;很大可能是由于在下载过程中存在网络问题&#xff0c;导致文件下载一半而停止&#xff0c;但是已经在仓库中存在这个文件夹&#xff0c;解决方法是删除文件夹重新下载即可。 删除本地仓库下的\org\apache\mav…

Gophish+EwoMail 自建钓鱼服务器

GophishEwoMail 自建钓鱼服务器 文章目录 GophishEwoMail 自建钓鱼服务器1.前提准备2.搭建EwoMail邮件服务器1&#xff09;Centos7 防火墙操作2&#xff09;设置主机名3&#xff09;host配置4&#xff09;安装EwoMail5&#xff09;获取DKIM6&#xff09;端口服务介绍7&#xff…

JAVA的学习日记

JAVA的学习日记&#xff08;2024.3.1&#xff09;&#xff08;b站韩顺平老师课程学习笔记版&#xff09; ps:捡起忘光光的Java语言 Sublime //1. public是公有&#xff0c;class是类 //2. public class Hello表示Hello是一个类&#xff0c;是一个public公有的类 //3. Hello{…

1.1 创建第一个vue项目

cmd命令窗口运行 vue init webpack hellovue 注意&#xff0c;hellovue是项目名称&#xff0c;项目名称不能保存大写字母否者会报错 Sorry, name can no longer contain capital letters. 运行设个命令的时候可能会报错&#xff0c;根据提示先运行 npm i -g vue/cli-init …

在独立Unity工程中集成Vortex Studio

本文首发于&#xff1a;Unity3D入门教程09.01&#xff1a;在独立Unity工程中集成Vortex Studio 目的 在Unity中使用Vortex Studio引擎模拟Unity场景中的任何资源。 工程 打开桌面Unity Hub快捷方式 点击Open选择需要打开的工程&#xff0c;这里选择官方提供的默认工程C:\CM…

永磁同步电机无感FOC(龙伯格观测器)算法技术总结-实战篇

文章目录 1、ST龙伯格算法分析&#xff08;定点数&#xff09;1.1 符号说明1.2 最大感应电动势计算1.3 系数计算1.4 龙伯格观测器计算1.5 锁相环计算1.6 观测器增益计算1.7 锁相环PI计算&#xff08;ST&#xff09;1.8 平均速度的用意 2、启动策略2.1 V/F压频比控制2.2 I/F压频…

msvcp140.dll安装教程_最新msvcp140.dll丢失的解决方法

msvcp140.dll 是一个动态链接库 (DLL) 文件&#xff0c;它是 Microsoft Visual C 运行时库的一部分&#xff0c;特别对应的是 Visual Studio 2015 版本编译的 C 应用程序所需的关键组件。DLL 文件的设计目的是为了实现代码和数据的共享&#xff0c;这样多个应用程序就可以在同一…

C# 解决uploadify插件上传时造成session丢失问题

出现的问题&#xff1a; 在应用uploadify插件实现上传图片时&#xff0c;报了HTTP Error&#xff0c;经过在Network查看上传方法报错码是302&#xff0c;那这里就可以知道问题是什么了&#xff0c;HTTP 302是请求被重定向&#xff0c;如果你的uploadify处理上传方法有session验…

Vue3_2024_1天【Vue3创建和响应式,对比Vue2】

前言&#xff1a; Vue3对比Vue2版本&#xff0c;它在性能、功能、易用性和可维护性方面都有显著的提升和改进。 性能优化&#xff1a;模板编译器的优化、对Proxy的支持以及使用了更加高效的Virtual DOM算法等。这使得Vue3的打包大小减少了41%&#xff0c;初次渲染提速55%&#…

【K8S类型系统】一文梳理 K8S 各类型概念之间的关系(GVK/GVR/Object/Schema/RestMapper)

参考 k8s 官方文档 https://kubernetes.io/zh-cn/docs/reference/https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/ 重点 Kubernetes源码学习-kubernetes基础数据结构 - 知乎 重点 Kubernetes类型系统 | 李乾坤的博客 重点 k8s源码学习-三大核心数…

Harbor 的安装及使用

Harbor 安装官网手册&#xff1a; https://goharbor.io/docs/2.10.0/install-config/download-installer/ Harbor 发布包地址&#xff1a; https://github.com/goharbor/harbor/releases Harbor 的架构查看&#xff1a; https://github.com/goharbor/harbor/wiki/Architectur…

​MPV,汽车产品里一个特殊品类的进化过程

「汽车」可能是整个工业革命以来&#xff0c;所诞生出的最有趣的工业产品。 它不仅能产生工业的机械美&#xff0c;还诞生了一个独立的文化体系&#xff0c;在汽车的发展过程中&#xff0c;我们也能看到一些本来应功能而诞生的产品&#xff0c;最终走向了千家万户。 MPV 就是…

如何设置从小程序跳转到其它小程序

​有的商家有多个小程序&#xff0c;希望能够通过一个小程序链接到所有其它小程序&#xff0c;用户可以通过点击跳转链接实现从一个小程序跳转到另一个小程序。要怎么才能实现这样的跳转呢。下面具体介绍。 1. 设置跳转。在小程序管理员后台->分类管理&#xff0c;添加一个…

js截取图片地址后面的参数和在路径中截取文件名或后缀名

文章目录 前言截取地址 &#xff1f;后面的参数在路径中截取文件名或后缀名总结 前言 在处理网页上的图片资源或者其他类型的文件资源时&#xff0c;你可能会遇到需要使用这些技巧的情况。以下是一些具体的使用场景&#xff1a; 动态修改图片参数&#xff1a;如果你有一个图片U…

社交APP开发能给用户带来什么

现在的社交软件也非常的多&#xff0c;每款社交软件都有自己的特色&#xff0c;社交软件是日常中必备的软件&#xff0c;不管是生活交流还是感情工作交流都是比较方便的&#xff0c;因为社交软件满足了日常的远程交流问题&#xff0c;所以开发社交软件也会逐渐的流行起来的。 …

LeetCode240题:搜索二维矩阵II(python3)

代码思路&#xff1a; “根节点” 对应的是矩阵的 “左下角” 和 “右上角” 元素&#xff0c;以 matrix 中的左下角元素为标志数 flag &#xff0c;则有: 若 flag > target &#xff0c;则 target 一定在 flag 所在行的上方 &#xff0c;即 flag 所在行可被消去&#xff0c…

NLP - 神经网络与反向传播

使用神经网络进行命名实体识别&#xff08;二值词窗分类&#xff09; 根据上下文窗口 建立词向量 通过一个神经网络层&#xff0c;通过一个逻辑分类器&#xff0c;得到这个概率是属于特定实体词的预测概率。 另一个分类器来比较说明 这个词是哪个实体类型&#xff08;比较概率…

基于Python3的数据结构与算法 - 07 归并排序

一、归并 引入 假设现在的列表分两段有序&#xff0c;如何将其合并成为一个有序列表。 这种操作成为一次归并。 归并的思路 分别对两个列表进行遍历&#xff0c;比较两个列表中的最小值&#xff0c;将更小的取出来。取出后一次进行上操作&#xff0c;直到其中一个列表中的元…

Servlet 新手村引入-编写一个简单的servlet项目

Servlet 新手村引入-编写一个简单的servlet项目 文章目录 Servlet 新手村引入-编写一个简单的servlet项目一、编写一个 Hello world 项目1.创建项目2.引入依赖3.手动创建一些必要的目录/文件4.编写代码5.打包程序6.部署7.验证程序 二、更方便的处理方案&#xff08;插件引入&am…
最新文章