【五一创作】VS+Qt主界面内嵌自定义控件的四种方法以及不同自定义控件数据交互

news2024/9/28 19:20:29

前言

在Qt界面开发过程中,一个主界面或者主窗口看成是各个控件排列组合后的集合,对于一些项目而言,有些常用的控件可以封装成自己想要的控件样式并且复用,比如说,log显示控件,图像/视频显示控件等,可以将常用的控件代码封装起来,以便下次复用,内嵌在不同的主界面内。这里总结了常见的四种方法供大家参考;

第一种方法:直接调用自定义控件项目文件至主界面项目中

  • 新建一个自定义控件项目
    在这里插入图片描述
    一般自定义控件,继承于QWidget;
    ui文件为
    在这里插入图片描述
  • 另建一个主界面项目,主界面ui文件如图所示,在主界面内添加一个QFrame,在Frame内添加一个布局控件(添加widget控件)
    在这里插入图片描述
  • 将自定义控件的.ui,.h,.cpp文件添加到主界面的项目中
  • 在主界面内添加自定义控件类,并建立自定义控件变量

头文件为

#include "CustomWidget.h"  //自定义控件

class MainWindows : public QMainWindow
{
    Q_OBJECT

public:
    MainWindows(QWidget *parent = Q_NULLPTR);
	
private:
	CustomWidget *customWidget;    //自定义控件
    Ui::MainWindowsClass ui;
};

cpp文件内

#include "MainWindows.h"

MainWindows::MainWindows(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
	//加载自定义控件
	customWidget = new CustomWidget;
	ui.layout->addWidget(customWidget);
	//调用自定义控件的接口
	customWidget->setText();
}

这样运行之后,便可以看到自定义控件内嵌到主界面内;
在这里插入图片描述

自定义控件和主界面之间的数据交互方法

主界面控制自定义控件:可以在子界面内建立一个数据接口函数,这样可以通过直接调用子界面类对象的函数,实现子界面内数据变化;比如说上述,自定义控件的接口setText()可以实现自定义控件的ui刷新;
自定义控件内数据传给主界面:通过信号槽的方式;
在这里插入图片描述

第二种方法:自定义控件编译成dll,主界面项目调用

  • 创建一个自定义控件项目文件,将项目的输出属性更改为dll
    在这里插入图片描述
    在这里插入图片描述

  • 在自定义控件类上要加入Q_DECL_EXPORT,这样才能输出lib文件

  • 自定义控件的ui文件与方法一相同,自定义控件类的.h文件为

#include <QtWidgets/QWidget>
#include "ui_CustomWidget.h"
//没有Q_DECL_EXPORT,就不会生成lib文件
class Q_DECL_EXPORT CustomWidget : public QWidget
{
    Q_OBJECT

public:
    CustomWidget(QWidget *parent = Q_NULLPTR);
	void setText(QString str);  //接口函数

private:
    Ui::CustomWidgetClass ui;

public slots:
	void on_openBtn();
};
  • 新建一个主界面项目,添加QFrame和布局,主控件布局和方法一一样,将自定义控件的dll文件,lib文件,.h文件添加到主界面项目中,注意,在.h文件发布的时候,需要提供ui_XXX.h,并且将.h文件中的Q_DECL_EXPORT去掉,不然会报错,主界面包含的头文件如图所示;
    在这里插入图片描述

发布的.h文件为

#include <QtWidgets/QWidget>
#include "ui_CustomWidget.h"
//发布时,去掉Q_DECL_EXPORT
class CustomWidget : public QWidget
{
}
  • 主界面的定义与方法一相同;主界面与自定义控件之间的数据交互也与方法一相同,最终的效果为
    在这里插入图片描述

第三种方法:在Qt Designer中提升控件

  • 新建一个自定义控件项目,自定义控件与方法一相同
  • 新建一个主界面项目,将自定义控件的ui文件,cpp文件,h文件添加到主界面项目中;因为ui编译顺序的问题,要把自定义控件的.h文件放到最前面,不然会报错;
#include "CustomWidget.h"  //自定义控件
#include <QtWidgets/QMainWindow>
#include <qpushbutton.h>
#include "ui_MainWindows.h"
  • 在主界面的Qt Designer中先新建一个QWidget控件,提升控件;选中控件,选择提升为
    在这里插入图片描述
    手动填入自定义控件类的类名称
    在这里插入图片描述
    可以在对象查看器中看到QWidget已经变成了CustomWidget,同时修改对象名称为customWidget,接下来便可以按照第一种方法,在主界面函数类访问自定义控件的数据;
    在这里插入图片描述

  • 最终主界面效果为
    在这里插入图片描述

第四种方法:自定义插件–Plugin方式

  • 首先在VS中创建一个Qt Designer Custom Widget项目并命名为CustomWidget。如图所示
    在这里插入图片描述
    创建好之后,可以看到并无ui文件。
    在这里插入图片描述

这里我们讲述的自定义控件是制作成插件的方式,因此设计阶段是需要ui文件的,这里需要在项目文件内自行创建一个ui文件。并且在CustomWidget.h内添加ui文件生成的ui_CustomWidget.h头文件。自行添加槽函数,ui对象等;

#pragma once

#include <QtWidgets/QWidget>
//自行添加ui生成的头文件
#include "ui_CustomWidget.h"

class CustomWidget : public QWidget
{
    Q_OBJECT

public:
    CustomWidget(QWidget *parent = Q_NULLPTR);

//自行添加ui界面的信号槽函数
public slots:
void on_openBtn();
//这里要跟ui_CustomWidget.h里面命名空间内的界面类对应上,自行添加
private:
	Ui::Form ui;
};


#include "CustomWidget.h"
CustomWidget::CustomWidget(QWidget *parent)
    : QWidget(parent)
{
	//自行添加的代码
	ui.setupUi(this);
	connect(ui.openBtn,&QPushButton::clicked,this,&CustomWidget::on_openBtn);
}
//自行添加槽函数
void CustomWidget::on_openBtn()
{
	ui.textBrowser->append("open widget");
}

可以看出,插件类CustomWidgetPlugin组合类CustomWidget,CustomWidget组合界面类Form;
在自定义插件的生成文件内可以看到:
在这里插入图片描述
自定义插件生成dll和lib文件;主界面动态加载dll文件即可;

  • 创建一个主界面项目文件,与前两个方法相同;
  • 在主界面内可以动态加载dll文件,便可以实现动态加载自定义控件;将dll放到exe同级目录下,动态加载代码为:
    头文件:
//插件的头文件
#include "CustomWidget.h"
#include "ui_CustomWidget.h"
//相应的头文件
#include <qpluginloader.h>
#include <QtUiPlugin/QDesignerCustomWidgetInterface>

动态加载代码为:

QPluginLoader loader("CustomWidget.dll");
	if (loader.load())
	{
		QObject *plugin = loader.instance();
		if (plugin)
		{
			QDesignerCustomWidgetInterface *widget = qobject_cast<QDesignerCustomWidgetInterface *>(plugin);
			if (widget)
			{
				//创建的子控件对象
				QWidget *customWidget = widget->createWidget(nullptr);
				ui.layout->addWidget(customWidget);
			}
		}
	}

最终界面效果为:
在这里插入图片描述

四种方法的总结

其实四种方法的本质是将自定义控件封装成一个专门的类,通过调用子控件类对象便可以实现内嵌自定义控件,在开发过程中,使用以上四种方法,相当于把界面分成了各个子模块,主界面通过调用这些子模块,可以实现团队之间快速开发工作;

不同自定义控件或窗口之间数据交互的方式

从主界面传递数据到嵌入的自定义子控件,可以通过直接调用子控件类的接口函数实现从主窗口到子窗口之间的数据传递;而子界面传递到主界面或者子界面之间的数据交互可以按照单例模式,建立一个传递信号的类。其本质是建立一个类,通过connect函数可以传递信号到信号,从而实现自定义控件到主界面之间的数据交互;此代码参考的博主文章为:
Qt 信号在多层次对象间传递 多层嵌套类对象之间信号传递
头文件为:

#include <QObject>
class TransmitSignals : public QObject
{
	Q_OBJECT
public:
	static TransmitSignals &GetInstance();
private:
	TransmitSignals();
	~TransmitSignals();
	TransmitSignals(const TransmitSignals &) = delete;
	TransmitSignals(const TransmitSignals &&) = delete;
	TransmitSignals &operator=(const TransmitSignals &) = delete;
signals:
    //传递数据
	//传给A界面数据
	void sigToAWidget(QString ret);
	//传给B界面数据
	void sigToBWidget(QString ret);
public slots:
};

.cpp文件为

#include "TransmitSignals.h"

TransmitSignals::TransmitSignals()
{
}

TransmitSignals::~TransmitSignals()
{
}
TransmitSignals& TransmitSignals::GetInstance()
{
	static TransmitSignals RobotControl;
	return RobotControl;
}

最终的效果为
在这里插入图片描述

结尾

上述方法的源代码已放置链接中,可下载后查看项目源码:
Qt主界面内嵌自定义控件的四种方法以及不同控件数据交互

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ros2】ros melodic迁移到ros2 dashing过程中碰到的问题及解决方法

序言 总结踩坑经历&#xff0c;以利他人 1. error: forming pointer to reference type … & 报错原因&#xff1a; ros2回调函数的参数不能是引用形式 &&#xff0c;需要去除& 解决方法&#xff1a; 如果是指针引用&#xff0c;直接去除引用 void Callback(con…

【Java开发】Spring Cloud 11:Gateway 配置 ssl 证书(https、http、域名访问)

最近研究给微服务项目配置 ssl 证书&#xff0c;如此才可以对接微信小程序&#xff08;需要使用 https 请求&#xff09;。传统单体项目来说&#xff0c;首先往项目中添加证书文件&#xff0c;然后在配置文件中配置 ssl 证书路径、密码等相关信息&#xff1b;那么微服务这么多项…

机器学习强基计划8-5:图解局部线性嵌入LLE算法(附Python实现)

目录 0 写在前面1 流形学习2 局部线性嵌入算法2.1 什么是局部线性嵌入&#xff1f;2.2 算法原理推导 3 Python实现3.1 算法流程3.2 核心代码3.3 可视化 0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的…

基于学生成绩管理系统(附源代码及数据库)

基于Ecplise&#xff0c;jsp的学生成绩管理系统 目录 登录页面 系统主页 管理员账号管理 学生查询 课程管理 成绩管理 后台数据库 源代码下载&#xff08;含数据库&#xff09; 毕设项目专栏 分为以下四大板块&#xff1a; 系统用户管理: 包含管理员账号管理&#…

【一起撸个DL框架】5 实现:自适应线性单元

CSDN个人主页&#xff1a;清风莫追欢迎关注本专栏&#xff1a;《一起撸个DL框架》GitHub获取源码&#xff1a;https://github.com/flying-forever/OurDL 文章目录 5 实现&#xff1a;自适应线性单元&#x1f347;1 简介2 损失函数2.1 梯度下降法2.2 补充 3 整理项目结构4 损失函…

第二十七章 Unity碰撞体Collision(下)

本章节我们继续研究碰撞体&#xff0c;并且探索一下碰撞体与刚体之间的联系。我们回到之前的工程&#xff0c;然后给我们的紫色球体Sphere1也添加一个刚体组件。如下所示 此时&#xff0c;两个球体都具备了碰撞体和刚体组件。接下来&#xff0c;我们Play运行查看效果 我们发现&…

第二十六章 Unity碰撞体Collision(上)

在游戏世界中&#xff0c;游戏物体之间的交互都是通过“碰撞接触”来进行交互的。例如&#xff0c;攻击怪物则是主角与怪物的碰撞&#xff0c;触发机关则是主角与机关的碰撞。在DirectX课程中&#xff0c;我们也大致介绍过有关碰撞检测的内容。游戏世界中的3D模型的形状是非常复…

浅谈区块链1.0-比特币

1. 比特币解决的问题 高度自治&#xff1a;国际经济危机无国界贸易&#xff1a;不同国家进行的贸易或者不同平台进行贸易 不可窜改&#xff1a;例如银行交易可能会被窜改数据 隐私安全&#xff1a;传统汇款方式会暴露你的个人信息&#xff0c;一旦数据库被别人入侵&#xff0c…

android基础知识复习

架构&#xff1a; 应用框架层&#xff08;Java API Framework&#xff09;所提供的主要组件&#xff1a; 名称功能描述Activity Manager&#xff08;活动管理器&#xff09;管理各个应用程序生命周期&#xff0c;以及常用的导航回退功能Location Manager&#xff08;位置管理器…

SpringBoot整合Mybatis-plus实现多级评论

在本文中&#xff0c;我们将介绍如何使用SpringBoot整合Mybatis-plus实现多级评论功能。同时&#xff0c;本文还将提供数据库的设计和详细的后端代码&#xff0c;前端界面使用Vue2。 数据库设计 本文的多级评论功能将采用MySQL数据库实现&#xff0c;下面是数据库的设计&…

Boonz-KeygenMe#1(★★★)

运行程序 错误&#xff1a; 查壳 没有壳&#xff0c;是汇编写的程序 载入OD 前面是在读取输入内容&#xff0c;到这里开始做计算了 分析 首先遍历了用户名&#xff0c;计算结果保存在EBX&#xff0c;在存放到 0x40E0F8 对EBX中的值再次计算&#xff0c;最后结果保存到 …

JavaFX: Java音乐播放读取歌词

JavaFX: Java音乐播放读取歌词 1、lrc歌词文件2、解析lrc歌词2.1 读取每行歌词2.2 解析歌词时间标签Time-tag2.3 解析歌词标识标签ID-tags2.4 创建对象包含歌词相关信息 3、播放显示歌词** 相关文献 JavaFX: Java音乐播放 1、lrc歌词文件 lrc歌词文件的扩展名 1、标准格式&a…

图像处理:Retinex算法

目录 前言 概念介绍 Retinex算法理论 单尺度Retinex&#xff08;SSR&#xff09; 多尺度Retinex&#xff08;MSR&#xff09; 多尺度自适应增益Retinex&#xff08;MSRCR&#xff09; Opencv实现Retinex算法 SSR算法 MCR算法 MSRCR算法 效果展示 总结 参考文章 前…

基频建模方法总结

基频F0建模方法 语音合成领域需要对基频进行建模&#xff0c;具体到文语转换TTS、语音转换VC、情感语音转换EVC领域等。 语音合成F0 包括文语转换&#xff0c;情感语音转换 TTEF&#xff1a;text-to-emotional-features synthesis EVC&#xff1a;emotional voice conversio…

这些你熟知的 app 和服务,都用上了人工智能

从微软在 Microsoft 365 服务中全面整合 GPT-4 能力 &#xff0c;让 PPT、Word 文档、Excel 表格的制作变成了「一句话的事」&#xff0c;到 Adobe 刚刚发布 Adobe Firefly模型集合&#xff0c;让图形设计、字体风格、视频渲染乃至 3D 建模的门槛显著降低——你我熟知的那些工…

idea的快捷键

一.idea的快捷键: 递进选择&#xff1a;ctrl w复制行&#xff1a;ctrl d删除行&#xff1a;ctrl y大小写切换&#xff1a;ctrl shift u展开/折叠&#xff1a;ctrl shift 减号/加号向前/向后&#xff1a;ctrl <— / —>Live Template(例如 输入psvm会自动打出mai…

华为OD机试题,用 Java 解【最远足迹】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不要…

Python实战项目:手势识别控制电脑音量

今天给大家带来一个OpenCV的实战小项目——手势识别控制电脑音量 先上个效果图&#xff1a; 通过大拇指和食指间的开合距离来调节电脑音量&#xff0c;即通过识别大拇指与食指这两个关键点之间的距离来控制电脑音量大小 技术交流 技术要学会分享、交流&#xff0c;不建议闭…

石英晶体振荡器【Multisim】【高频电子线路】

目录 一、实验目的与要求 二、实验仪器 三、实验内容与测试结果 1、观察输出波形&#xff0c;测量振荡频率和输出电压幅度 2、测量静态工作点的变化范围(IEQmin~IEQmax) 3、测量当静态工作点在上述范围时输出频率和输出电压的变化 4、测量负载变化对振荡频率和输出电压幅…

SpringCloud:微服务保护之初识Sentinel

1.初识Sentinel Sentinel是阿里巴巴开源的一款微服务流量控制组件。Sentinel官网 Sentinel具有以下特征&#xff1a; 丰富的应用场景&#xff1a;Sentinel承接了阿里巴巴近 10 年的双十一大促流量的核心场景&#xff0c;例如秒杀&#xff08;即突发流量控制在系统容量可以承受…