? ?前言? ? ? ??
????????QT創(chuàng)建窗體工程,一般在MainWindow或Dialog類(lèi)里可以直接通過(guò)ui指針訪問(wèn)控件,但是添加新的類(lèi)后又如何訪問(wèn)呢,可以通過(guò)以下幾種方式:
將ui指針公開(kāi)后直接訪問(wèn)
(1)例如有個(gè)自己定義的類(lèi)CustomClass,在自定義類(lèi)里包含主界面指針MainWindow *
class MainWindow;
?
class CustomClass
{
public:
? ? CustomClass(MainWindow * parent);
? ? MainWindow * mainwidow;
? ?void SetUI();
};
(2)主界面類(lèi)將成員Ui::MainWindow *ui 從私有private移動(dòng)到public公共
class MainWindow : public QMainWindow
{
? ? Q_OBJECT
? ??
public:
? ? MainWindow(QWidget *parent = nullptr);
? ? ~MainWindow();
? ? Ui::MainWindow *ui;
? ? CustomClass* customclass;
private: ??
}
(3)自定義類(lèi)包含頭文件:#include "ui_mainwindow.h",構(gòu)造的時(shí)候傳入界面指針MainWindow*,就能通過(guò) mainwidow->ui指針訪問(wèn)UI控件了。
#include "mainwindow.h"
#include "ui_mainwindow.h"
?
CustomClass::CustomClass(MainWindow * parent)
{
? this->mainwidow = parent;
}
?
void CustomClass::SetUI()
{
? ? mainwidow->ui->pushButton->setText("開(kāi)始");
}
記得要引用ui_mainwindow.h,不然會(huì)報(bào)錯(cuò)誤:
error: member access into incomplete type 'Ui::MainWindow'
forward declaration of 'Ui::MainWindow'
封裝成公共函數(shù)
(1)所有對(duì)UI的操作都在主界面MainWindow類(lèi)中,并封裝成公共的函數(shù)
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("開(kāi)始");
}
(2)其他類(lèi)要訪問(wèn)UI調(diào)用函數(shù)就好了
CustomClass::CustomClass(MainWindow * parent)
{
? this->mainwidow = parent;
? this->mainwidow->SetUI();
}
通過(guò)控件指針訪問(wèn)
如果每次只訪問(wèn)一兩個(gè)控件的話,也可以直接將控件指針傳給自定義類(lèi)customclass=new CustomClass(this);
? ? customclass->SetUI(ui->pushButton);
void CustomClass::SetUI(QPushButton* btn)
{
? ? btn->setText("開(kāi)始");
}
通過(guò)信號(hào)和槽訪問(wèn)
前面的方法一般夠用了,但如果是多線程就必須用到信號(hào)和槽機(jī)制,因?yàn)榉荱I線程不能跨線程訪問(wèn)UI,例如定義一個(gè)線程類(lèi)
class MyThread :public QThread
{
? ? Q_OBJECT
public:
? ? MyThread(MainWindow *parent);
? ? MainWindow * mainwidow;
? ? void run() override;
};
在主界面MainWindow類(lèi)里有信號(hào)setui,和槽函數(shù)SetUI,所有對(duì) UI的操作都封裝在槽函數(shù)函數(shù)中
MainWindow::MainWindow(QWidget *parent)
? ? : QMainWindow(parent)
? ? , ui(new Ui::MainWindow)
{
? ? ui->setupUi(this);
? ? //關(guān)聯(lián)信號(hào)
? ? ?connect(this,&MainWindow::setui,this,&MainWindow::SetUI);
? ? ?mythread = new MyThread(this);
? ? ?mythread->start();//啟動(dòng)線程
}
?
void MainWindow::SetUI()
{
? ? this->ui->pushButton->setText("開(kāi)始");
}
在非UI線程里需要訪問(wèn)Ui通過(guò)發(fā)送信號(hào)就行了,槽函數(shù)會(huì)在UI線程中被執(zhí)行
void MyThread::run()
{
? ? //發(fā)送信號(hào),修改UI
? ? emit this->mainwidow->SetUI();
? ? exec();
}
當(dāng)然信號(hào)和槽很靈活,不一定在多線程中,有需要都可以用。
/****************************************
在子線程里控制主界面的UI控件有兩種方法:第一種是在子線程中發(fā)送信號(hào),然后在主線程中去更新;第二種方法是在子線程中創(chuàng)建同樣的對(duì)象,然后把主界面中控件的指針賦給創(chuàng)建的對(duì)象。
第一種方法在此不做實(shí)例展示,在此通過(guò)一個(gè)簡(jiǎn)單的例子展示第二種方法:
下面是主界面的初始轉(zhuǎn)態(tài):
下面這個(gè)是繼承自QThread類(lèi)的子線程類(lèi)
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("更新");
}
下面是主線程類(lèi)
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; ?//創(chuàng)建子線程對(duì)象
? ? sonthread->label=ui->label; ?//將主界面UI指針賦給子線程中的指針對(duì)象
? ? sonthread->start(); ?//啟動(dòng)子線程
? ? qDebug()<<"Dialog()"<<QThread::currentThreadId();
}
Dialog::~Dialog()
{
? ? delete ui;
}
下面是運(yùn)行結(jié)果:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-707355.html
可以看出run()函數(shù)與主線程不在同一個(gè)線程,而我只在run()中有修改過(guò)label的字符,所以實(shí)現(xiàn)了在子線程中操作主界面UI控件的目的。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-707355.html
到了這里,關(guān)于QT子線程或自定義類(lèi)操作訪問(wèn)主界面UI控件的幾種方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!