QT 自定义类访问UI控件的几种方法

前言

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

1.将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'

 

2.封装成公共函数

(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();
}

3.通过控件指针访问

如果每次只访问一两个控件的话,也可以直接将控件指针传给自定义类

    customclass=new CustomClass(this);
    customclass->SetUI(ui->pushButton);
void CustomClass::SetUI(QPushButton* btn)
{
    btn->setText("开始");
}

4.通过信号和槽访问

前面的方法一般够用了,但如果是多线程就必须用到信号和槽机制,因为非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();
}

当然信号和槽很灵活,不一定在多线程中,有需要都可以用。

  • 22
    点赞
  • 176
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哀歌与世无争

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值