QT子线程或自定义类操作访问主界面UI控件的几种方法

   前言        

        QT创建窗体工程,一般在MainWindow或Dialog类里可以直接通过ui指针访问控件,但是添加新的类后又如何访问呢,可以通过以下几种方式:

将ui指针公开后直接访问

(1)例如有个自己定义的类CustomClass,在自定义类里包含主界面指针MainWindow *

class MainWindow;
 
class CustomClass
{
public:
    CustomClass(MainWindow * parent);
    MainWindow * mainwidow;
   void SetUI();
};
(2)主界面类将成员Ui::MainWindow *ui 从私有private移动到public公共

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    Ui::MainWindow *ui;
    CustomClass* customclass;
private:   
}
(3)自定义类包含头文件:#include "ui_mainwindow.h",构造的时候传入界面指针MainWindow*,就能通过 mainwidow->ui指针访问UI控件了。

#include "mainwindow.h"
#include "ui_mainwindow.h"
 
CustomClass::CustomClass(MainWindow * parent)
{
  this->mainwidow = parent;
}
 
void CustomClass::SetUI()
{
    mainwidow->ui->pushButton->setText("开始");
}
记得要引用ui_mainwindow.h,不然会报错误:

error: member access into incomplete type 'Ui::MainWindow'

forward declaration of 'Ui::MainWindow'

封装成公共函数

(1)所有对UI的操作都在主界面MainWindow类中,并封装成公共的函数

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
     void SetUI();
    CustomClass* customclass;
private:   
        Ui::MainWindow *ui;
}
 
void MainWindow::SetUI()
{
    this->ui->pushButton->setText("开始");
}
(2)其他类要访问UI调用函数就好了

CustomClass::CustomClass(MainWindow * parent)
{
  this->mainwidow = parent;
  this->mainwidow->SetUI();
}


通过控件指针访问


如果每次只访问一两个控件的话,也可以直接将控件指针传给自定义类customclass=new CustomClass(this);
    customclass->SetUI(ui->pushButton);
void CustomClass::SetUI(QPushButton* btn)
{
    btn->setText("开始");
}

通过信号和槽访问


前面的方法一般够用了,但如果是多线程就必须用到信号和槽机制,因为非UI线程不能跨线程访问UI,例如定义一个线程类

class MyThread :public QThread
{
    Q_OBJECT
public:
    MyThread(MainWindow *parent);
    MainWindow * mainwidow;
    void run() override;
};
在主界面MainWindow类里有信号setui,和槽函数SetUI,所有对 UI的操作都封装在槽函数函数中

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //关联信号
     connect(this,&MainWindow::setui,this,&MainWindow::SetUI);
     mythread = new MyThread(this);
     mythread->start();//启动线程
}
 
void MainWindow::SetUI()
{
    this->ui->pushButton->setText("开始");
}
在非UI线程里需要访问Ui通过发送信号就行了,槽函数会在UI线程中被执行

void MyThread::run()
{
    //发送信号,修改UI
    emit this->mainwidow->SetUI();
    exec();
}
当然信号和槽很灵活,不一定在多线程中,有需要都可以用。

/****************************************

在子线程里控制主界面的UI控件有两种方法:第一种是在子线程中发送信号,然后在主线程中去更新;第二种方法是在子线程中创建同样的对象,然后把主界面中控件的指针赋给创建的对象。

第一种方法在此不做实例展示,在此通过一个简单的例子展示第二种方法:
下面是主界面的初始转态:

下面这个是继承自QThread类的子线程类
sonthread.h

#ifndef SONTHREAD_H
#define SONTHREAD_H

#include <QLabel>
#include <QThread>
#include <QDebug>

class sonThread : public QThread
{
    Q_OBJECT
public:
    explicit sonThread(QObject *parent = nullptr);
    void run();

public:
    QLabel *label;
};

#endif // SONTHREAD_H

sonthread.cpp

#include "sonthread.h"

sonThread::sonThread(QObject *parent) : QThread(parent)
{
    label = new QLabel;
}

void sonThread::run()
{
    qDebug()<<"run()"<<QThread::currentThreadId();
    
    label->setText("更新");
}

下面是主线程类
dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QThread>
#include "sonthread.h"

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();


private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"


Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    sonThread *sonthread = new sonThread;  //创建子线程对象
    sonthread->label=ui->label;  //将主界面UI指针赋给子线程中的指针对象
    sonthread->start();  //启动子线程

    qDebug()<<"Dialog()"<<QThread::currentThreadId();

}

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

下面是运行结果:

可以看出run()函数与主线程不在同一个线程,而我只在run()中有修改过label的字符,所以实现了在子线程中操作主界面UI控件的目的。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 官方屏幕适配之ScreenMatch

背景&#xff1a; Android 项目的一个app需要适配手机平板&#xff0c;为了一套UI和可以适配2个不同屏幕&#xff0c;记录一个适配的技巧&#xff1a; 前提&#xff0c;使用这个框架&#xff1a;GitHub - wildma/ScreenAdaptation: :fire:一种非常好用的 Android 屏幕适配——…

Leetcode: 645.错误的集合 题解【超详细】

题目 集合 s 包含从 1 到 n 的整数。不幸的是&#xff0c;因为数据错误&#xff0c;导致集合里面某一个数字复制了成了集合里面的另外一个数字的值&#xff0c;导致集合 丢失了一个数字 并且 有一个数字重复 。 给定一个数组 nums 代表了集合 S 发生错误后的结果。 请你找出重复…

【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(9 月 15 日论文合集)

文章目录 一、检测相关(6篇)1.1 ALWOD: Active Learning for Weakly-Supervised Object Detection1.2 mEBAL2 Database and Benchmark: Image-based Multispectral Eyeblink Detection1.3 Co-Salient Object Detection with Semantic-Level Consensus Extraction and Dispersio…

[npm]package.json文件

[npm]package.json文件 生成 package.jsonpackage.json 必须属性nameversion 描述信息descriptionkeywordsauthorcontributorshomepagerepositorybugs 依赖配置dependenciesdevDependenciespeerDependenciesoptionalDependenciesbundledDependenciesengines 脚本配置scriptscon…

spring boot 使用AOP+自定义注解+反射实现操作日志记录修改前数据和修改后对比数据,并保存至日志表

一、添加aop starter依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>二&#xff1a;自定义字段翻译注解。&#xff08;修改功能时&#xff0c;需要显示如…

SpringBoot整合Easy-ES实现对ES操作

请确保已有可用的ES&#xff0c;若没有&#xff0c;请移步&#xff1a;Docker安装部署ElasticSearch&#xff08;ES&#xff09; 新建SpringBoot项目 这里是用的springboot版本是2.6.0 引入依赖 <!-- 排除springboot中内置的es依赖,以防和easy-es中的依赖冲突--><…

Python解析MDX词典数据并保存到Excel

原始数据和处理结果&#xff1a; https://gitcode.net/as604049322/blog_data/-/tree/master/mdx 下载help.mdx词典后&#xff0c;我们无法直接查看&#xff0c;我们可以使用readmdict库来完成对mdx文件的读取。 安装库&#xff1a; pip install readmdict对于Windows平台还…

分析报告显示,PHP是编程语言主力军,且在电商领域占据“统治地位”

日前有有业内专家透露了PHP语言的使用数据&#xff0c;并强调了PHP语言对于互联网的作用。 而根据W3 Techs发布的《全球前1000万个网站使用的编程语言分析(截至 2023.8)》中&#xff0c;有这样一组数据引起广泛的关注。PHP占比 77.2%、ASP占比 6.9%、Ruby 占比5.4%。 此外&am…

BLE架构与开源协议栈

BLE架构&#xff1a; 简单来说&#xff0c;BLE协议栈可以分成三个部分&#xff0c;主机(host)程序&#xff0c;控制器(controller)程序&#xff0c;主机控制器接口(HCI)。如果再加上底层射频硬件和顶层用户程序&#xff0c;则构成了完整的BLE协议&#xff0c;如下图所示&#…

Python用若干列的数据多条件筛选、去除Excel数据并批量绘制直方图

本文介绍基于Python&#xff0c;读取Excel数据&#xff0c;以一列数据的值为标准&#xff0c;对这一列数据处于指定范围的所有行&#xff0c;再用其他几列数据数值&#xff0c;加以筛选与剔除&#xff1b;同时&#xff0c;对筛选与剔除前、后的数据分别绘制若干直方图&#xff…

conda常用命令及问题解决-创建虚拟环境

好久没写博文了&#xff0c;感觉在学习的过程中还是要注意积累与分享&#xff0c;这样利人利己。 conda包清理&#xff0c;许多无用的包是很占用空间的 conda clean -p //删除没有用的包 conda clean -y -all //删除pkgs目录下所有的无用安装包及cacheconda创建虚拟环境…

国外报告90%的AI类产品公司已经实现盈利,而国内大模型和AIGC的访谈说太卷了...

“ 国外AIGC产品的发展情况&#xff1a;市场规模不断扩大&#xff0c;用户付费意愿高&#xff0c;小团队创业成功率高。国内大模型行业的发展情况&#xff1a;行业内卷严重&#xff0c;商业化难题突出&#xff0c;技术挑战仍存。” 01 — diChatGPT发布已有9个月&#xff0c;月…