我有一個Qt專案(在Win10中),在我的MainWindow cpp檔案中需要一個非成員函式。這是一個回呼函式,當連接的傳感器的資料到達時,會從一個外部庫中自動觸發。我想在一個MainWindow部件(一個純文本編輯器)上顯示這些資料,但當然我不能從我的回呼函式中訪問任何MainWindow元素,而且到目前為止也沒有信號槽的概念。下面是這個問題的一個最小的例子:
MainWindow的元素是什么?
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMutex>/span>
qt_begin_namespace
namespace Ui { class MainWindow; }
qt_end_namespace
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr)。
~MainWindow()。
void displayData();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
MainWindow.cpp:
#include "mainwindow.h"/span>
#include "ui_mainwindow.h"
//定義全域變數
QMutex mutex。
bool new_data_arrived = false;
QString newDataStr;
void newData() {
//這是一個回呼函式,當通過USB連接的傳感器的資料到達時觸發。
//我想把結果作為一個QString傳遞給MainWindow::displayData(),以便在螢屏上顯示出來。
mutex.lock()。
new_data_arrived = true;
newDataStr = "新資料"。
mutex.unlock()。
};
void MainWindow::displayData()
{
mutex.lock()。
if (new_data_arrived == true) {
new_data_arrived = false;
ui->plainTextEdit->appendPlainText(newDatastr)。
}
mutex.unlock()。
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this)。
}
MainWindow::~MainWindow()
{
delete ui;
}
函式MainWindow::displayData()然后在一個回圈中運行(但這對我的問題不重要,所以我把它從上面的最小例子中洗掉了...)。
如前所述,newData()不能訪問MainWindow的任何元素,這很明顯。到目前為止,我發現的唯一解決方法是使用全域變數,如上圖所示,從非成員函式newData()中獲取資料到成員函式displayData()。我還包含了一個mutex,以避免可能的共享違規(不知道這是否有必要,但也無妨...)。
是否有一個更優雅的方法?原則上,我需要的是一個信號槽的概念,但是newData()不能發射MainWindow的信號,或者將this放入函式newData()中,這樣就可以訪問ui元素。
uj5u.com熱心網友回復:
你應該使用QMetaObject::invokeMethod來從一個非QObject槽(你的回呼函式)中呼叫一個QObject槽。
這里有一個例子:
class MainWindow : public QMainWindow
{
Q_OBJECT
/...
public slots:
void displayData( QString szNewData ) 。
};
//Cpp MainWindow.cpp file
static MainWindow * mainWindowObj = nullptr;
void setMainWindowObj( MainWindow * ptr ) {
mainWindowObj = ptr;
}
void newData() {
//這是一個回呼函式,當通過USB連接的傳感器的資料到達時觸發。
// I want to pass the result as a QString to MainWindow::displayData() to display it on screen .
if( mainWindowObj == nullptr )
return;
QMetaObject::invokeMethod( mainWindowObj, //pointer to MainWindow instance ( see main.cpp)
"displayData", //插槽名稱。
Qt::QueuedConnection, //連接型別。
Q_ARG( QString, newDataStr ); //Param passed to the slot void MainWindow::displayData( QString szNewData )/span>
{
ui->plainTextEdit->appendPlainText( szNewData ) 。
}
//main.cpp檔案或MainWindow實體被初始化的地方。
void setMainWindowObj(MainWindow * ptr )。
int main( int argc, char *argv[] ) /span>{
//....
QApplication app(argc, argv)。
//....
MainWindow mainWindow。
setMainWindowObj ( &mainWindow ) 。
//....。
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/310168.html
標籤:
