QMetaObject::invokeMethod
用于在运行时调用对象的槽或成员函数,可以在不同线程之间调度信号槽连接,或者在对象未导出的情况下调用其槽函数。
bool QMetaObject::invokeMethod(
QObject *obj,
const char *member,
Qt::ConnectionType type = Qt::AutoConnection,
QGenericReturnArgument ret = QGenericReturnArgument(0),
QGenericArgument val0 = QGenericArgument(0),
QGenericArgument val1 = QGenericArgument(0),
QGenericArgument val2 = QGenericArgument(0),
QGenericArgument val3 = QGenericArgument(0),
QGenericArgument val4 = QGenericArgument(0),
QGenericArgument val5 = QGenericArgument(0),
QGenericArgument val6 = QGenericArgument(0),
QGenericArgument val7 = QGenericArgument(0),
QGenericArgument val8 = QGenericArgument(0),
QGenericArgument val9 = QGenericArgument(0)
);
obj: 目标对象的指针。
member: 要调用的成员函数的名称,可以是槽或其他成员函数。
type: 连接类型,可以是 Qt::DirectConnection, Qt::QueuedConnection, Qt::BlockingQueuedConnection 等,默认是 Qt::AutoConnection。
ret: 返回值。
val0 到 val9: 传递给函数的参数,最多可以传递 10 个。
举例调用无参槽函数
class MyClass : public QObject
{
Q_OBJECT
public slots:
void mySlot() {
qDebug() << "mySlot called!";
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyClass obj;
// 调用 mySlot
QMetaObject::invokeMethod(&obj, "mySlot");
return app.exec();
}
调用有参槽函数
class MyClass : public QObject
{
Q_OBJECT
public slots:
void mySlotWithArgs(int value, const QString &text) {
qDebug() << "mySlotWithArgs called with value:" << value << "and text:" << text;
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyClass obj;
// 调用 mySlotWithArgs,传递参数 42 和 "Hello"
QMetaObject::invokeMethod(&obj, "mySlotWithArgs",
Q_ARG(int, 42),
Q_ARG(QString, "Hello"));
return app.exec();
}
跨线程调用槽函数
class Worker : public QObject
{
Q_OBJECT
public slots:
void doWork() {
qDebug() << "doWork called in thread:" << QThread::currentThread();
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Worker worker;
QThread workerThread;
worker.moveToThread(&workerThread);
workerThread.start();
// 使用 Qt::QueuedConnection 确保 doWork 在 workerThread 中被调用
QMetaObject::invokeMethod(&worker, "doWork", Qt::QueuedConnection);
// 确保主线程等待 workerThread 结束
QThread::sleep(1); // 假设一些处理时间
workerThread.quit();
workerThread.wait();
return app.exec();
}
QWidget *DBG::pMainWindow 和 Ui::MainWindow *ui
DBG::pMainWindow
是一个指向QWidget
对象的指针,通常表示应用程序的主窗口或某个主要窗口。- 由于它是一个全局静态指针(假设
DBG
是一个类或命名空间),它可以在整个应用程序中访问和使用。 Ui::MainWindow *ui
:ui
是一个指向Ui::MainWindow
对象的指针,Ui::MainWindow
通常是由 Qt Designer 生成的 UI 类,包含对主窗口中所有 UI 元素的引用。- 它通常在主窗口类(如
MainWindow
)的构造函数中初始化,以便在代码中访问和操作 UI 元素。 - mainwindow.h
-
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "ui_mainwindow.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
mainwindow.cpp
-
#include "mainwindow.h" #include "dbg.h" // 假设 DBG::pMainWindow 在这里定义 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); DBG::pMainWindow = this; // 将 pMainWindow 指向当前的 MainWindow 对象 } MainWindow::~MainWindow() { delete ui; }
dbg.h
-
#ifndef DBG_H #define DBG_H #include <QWidget> class DBG { public: static QWidget *pMainWindow; }; #endif // DBG_H
dbg.cpp
#include "dbg.h" QWidget *DBG::pMainWindow = nullptr;
QWidget *DBG::pMainWindow
和Ui::MainWindow *ui
可以共存,并且各自扮演不同的角色。前者通常用于全局访问主窗口,后者用于访问和操作由 Qt Designer 生成的 UI 元素。在主窗口类的构造函数中,你可以将DBG::pMainWindow
指向主窗口实例,以便在其他地方可以访问主窗口。