延时初始化

1.延时初始化

class() //构造函数
{
//基本初始化
initial()//一些依赖项的初始化
}
由于一些原因(需要事件循环,依赖其他项启动,线程问题),initial会初始化失败

使用: QTimer::singleShot(0, this, &MyClass::initial);
0意味着进入事件循环后,它会立即执行initial,而不是在构造中执行(在构造函数完成并且控制返回给事件循环后立即执行)

2.QMetaObject::invokeMethod方法详解
QMetaObject::invokeMethod:此方法允许你指定一个连接类型(如 Qt::QueuedConnection),从而确保方法调用被安排到目标对象所属线程的事件队列中,等待该线程的事件循环处理。
其本质是“安排”,而非直接调用,

例如:bool res=QMetaObject::invokeMethod(p_button,"setText",Qt::QueuedConnection,Q_ARG(QString, "dididi"));
首先需要目标对象的指针,p_button
那我都知道指针了,为何不直接调用它的方法?
原因:跨线程:可以将方法调用放入目标线程的事件队列中,等待该线程的事件循环处理。这对于 GUI 编程尤其重要,因为所有与界面相关的操作都必须在主线程(即 UI 线程)中执行。

假设你有一个多线程应用,其中有一个后台线程需要通知主界面更新显示。如果直接调用主界面对象的方法可能会导致线程安全问题,而使用 QMetaObject::invokeMethod 则可以避免这些问题:

class MainWidget : public QWidget {
    Q_OBJECT
public slots:
    void updateDisplay(const QString &text) {
        // 更新UI
        label->setText(text);
    }
};

// 在后台线程中
void someFunctionInAnotherThread(MainWidget *widget) {
    // 使用invokeMethod确保updateDisplay在主界面线程中执行
    QMetaObject::invokeMethod(widget, "updateDisplay",
                              Qt::QueuedConnection,
                              Q_ARG(QString, QStringLiteral("New Text")));
}

通过方法名字符串来调用槽函数或标记为 Q_INVOKABLE 的成员函数,只声明为public是无法调用的

posted on 2025-03-16 22:45  不败剑坤  阅读(274)  评论(0)    收藏  举报

导航