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控件的目的。

相关推荐
是娇娇公主~6 小时前
C++ 中 std::deque 的原理?它内部是如何实现的?
开发语言·c++·stl
SuperEugene6 小时前
Axios 接口请求规范实战:请求参数 / 响应处理 / 异常兜底,避坑中后台 API 调用混乱|API 与异步请求规范篇
开发语言·前端·javascript·vue.js·前端框架·axios
xuxie997 小时前
N11 ARM-irq
java·开发语言
wefly20178 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
luanma1509808 小时前
PHP vs C++:编程语言终极对决
开发语言·c++·php
寂静or沉默8 小时前
2026最新Java岗位从P5-P7的成长面试进阶资源分享!
java·开发语言·面试
liwenzhuola9 小时前
解决 Ubuntu 上 Qt Creator 项目编译失败的问题
数据库·qt·ubuntu
kyriewen119 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript
娇娇yyyyyy10 小时前
QT编程(18): Qt QItemSelectionModel介绍
开发语言·qt
豆豆的java之旅10 小时前
软考中级软件设计师 数据结构详细知识点(含真题+练习题,可直接复习)
java·开发语言·数据结构