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

这篇具有很好参考价值的文章主要介绍了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控件有两种方法:第一种是在子线程中发送信号,然后在主线程中去更新;第二种方法是在子线程中创建同样的对象,然后把主界面中控件的指针赋给创建的对象。

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

QT子线程或自定义类操作访问主界面UI控件的几种方法,QT,qt,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;
}

下面是运行结果:

QT子线程或自定义类操作访问主界面UI控件的几种方法,QT,qt,ui,开发语言

可以看出run()函数与主线程不在同一个线程,而我只在run()中有修改过label的字符,所以实现了在子线程中操作主界面UI控件的目的。文章来源地址https://www.toymoban.com/news/detail-707355.html

到了这里,关于QT子线程或自定义类操作访问主界面UI控件的几种方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QT在自定义类中调用主类(界面类ui及其控件)的一种实用方法

    在实际应用中,经常会出现需要自定义类访问界面中的控件的情况,使用信号和槽进行跳转往往过于繁琐,使用下述方法可以巧妙解决: 界面类 QtWidgetsTest.h QtWidgetsTest.cpp 自定义类 CustomClass.h 首先包含ui头文件(其实也可不写,因为cpp里一定会包含QtWidgetsTest.h并包含ui文件),

    2024年02月16日
    浏览(33)
  • 【Visual Studio】Qt 在其他 cpp 文件中调用操作 ui 界面控件

    知识不是单独的,一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏:Visual Studio。 还整了一个如何相互之间调用函数的文章,感兴趣可以看:【Visual Studio】Qt 在其他 cpp 文件中调用主工程下文件中的函数。 主界面工程为 A ,添加的文件名字为 test ,目标是在

    2024年02月05日
    浏览(39)
  • c# 跨线程访问UI控件

            在一个应用程序中,往往存在两种线程:UI线程和工作线程。         UI线程有窗口,创建窗口的控件,且有消息队列对窗口和控件的消息进行管理。主要处理和UI相关的逻辑。         工作线程主要处理和业务相关的比较复杂的逻辑,当处理好之后有可能会调用U

    2024年02月08日
    浏览(30)
  • QT自定义优雅的表单控件,简单实现设置界面布局

    FormView.h FormView.cpp 核心函数 函数 变量 功能 addEditableItem title: 输入框前面的提示文字,同时作为该控件的标识符 place_holder: 输入框中的提示文字 在表单中插入一个可填写项 addCheckableItem title: 不显示在UI中,仅作为该控件的标识符 content: 勾选框后面的内容 init_status: 勾选框的初

    2024年02月11日
    浏览(33)
  • C#线程操作UI控件

    在写winform程序时候,如果时间长的操作不用线程操作。那么会卡死UI,点击界面就体现为未响应。为此需要对耗时操作用线程处理,比如检验的监听程序就是一个死循环,不停检查文件夹或数据库又没有数据,然后上传。如果不时有线程,在数据多的情况,程序是基本点不动

    2024年02月13日
    浏览(26)
  • c#WPF 自定义UI控件学习,vb.net界面UI美化

    最近项目中运用到了WPF处理三维软件,在C/S结构中WPF做UI还是有很多优越性,简单的学了一点WPF知识,成功的完成项目目标。项目过度阶段对于WPF的一些基本特点有了进一步了解 。至此花费一点时间研究研究WPF控件。 为以后的项目开发中提供一些可观的资源也是不错的。 目

    2024年02月20日
    浏览(37)
  • 【五一创作】VS+Qt主界面内嵌自定义控件的四种方法以及不同自定义控件数据交互

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

    2024年02月11日
    浏览(51)
  • C#中错误:线程间操作无效,从不是创建控件的线程访问它。

    一、原因分析 跨线程调用控件会出现这个错误的原因是因为:.NET禁止了跨线程调用控件, 否则谁都可以操作控件,最后可能造成错误。 所以不是在创建控件所在的线程内调用就会发生这样的错误。 二、解决办法 方法1:设置CheckForIllegalCrossThreadCalls =false 是能去掉这个检查的

    2024年02月15日
    浏览(26)
  • C#线程间操作无效:从不是创建控件“textbox1”的线程访问它

    在C#的多线程访问中,在线程间的相互访问时因为线程安全问题有访问限制,在创建一般线程时,对于界面元素访问时这样的问题比较常见。 比如,创建一个form1,上面放置一个textbox控件,创建一个线程去访问textbox,界面如下: 按钮buuton1的代码: 就是简单地创建一个线程,

    2023年04月09日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包