c++ - 启动 Qt5 控制台应用程序 : invokemethod vs singleshot timer

标签 c++ qt qt5

我已经看到了两种不同的方式来启动 Qt 控制台应用程序,即在事件循环启动时调用类方法。 This way一旦事件循环开始,将要调用的方法排队,this way运行一个 singleShot 计时器,该计时器在事件循环开始后不久触发一个插槽执行。在这两种情况下,目标都是在执行类方法之前让事件循环运行。

这些对我来说似乎都不是特别干净,但我没有看到更好的东西。我对 Qt 也没有太多经验,那我该说谁呢?

无论哪种方式都有优势吗? invokeMethod 方式(第一个链接)似乎不像 singleShot 计时器方式(第二个链接)那样常见,但除此之外,我没有理由遵循一种模式而不是另一种模式。

谢谢!

最佳答案

QTimer::singleShot()有一个采用函数指针(成员函数、仿函数或 lambda)的重载。

使用此重载将提供编译时检查,这比使用函数名称时获得的运行时检查要好。此外,被调用的函数不需要是插槽。

从 Qt 5.8 开始,QMetaObject::invokeMethod() 没有这样的重载。所以你被困在使用他们的名字来调用插槽。请注意,此功能将在 Qt 5.10 中添加。

恕我直言,编译时间检查足以使用 QTimer::singleShot() (将 QMetaObject::invokeMethod() 放在一边,直到 5.10 结束)。

同样正如@Jeremy 指出的那样,调用 QTimer::singleShot()以 0 毫秒的延迟结束调用 QMetaObject::invokeMethod() ,但前提是您使用的是采用插槽名称的重载(因此没有编译时检查)。 QTimer::singleShot() 的过载采用函数指针的函数在 0 ms 的情况下没有这种优化,并且可能需要更多的 CPU 和内存来设置。

总结一下:

MyObject *object;

// 1: No compile time check for slot1, may fail at run time if slot1() does not exist
QMetaObject::invokeMethod(object, "slot1", Qt::QueuedConnection);

// 2: Calls 1 internally, but needs to do dome string editing to remove the decoration added by SLOT()
QTimer::singleShot(0, object, SLOT(slot1()));

// 3: Compile time check (i.e slot1() must exist), but creates a QSingleShotTimer internally (maybe less optimized)
QTimer::singleShot(0, object, &MyObject::slot1);
// QTimer::singleShot(0, [&](){printf("\o/"); object->slot1();}); // It can also call lambda 

// In any case, slot1 will be called as soon as event processing starts
app.exec()

关于c++ - 启动 Qt5 控制台应用程序 : invokemethod vs singleshot timer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43671504/

相关文章:

c++ - 如何在小型聊天应用程序中为数据库存储的用户事务建模?

c++ - 修改 .ui 文件需要一个 `make clean`

c++ - 当组合框为空时不应触发组合框连接信号

qt - 如何找到 QMediaPlayer 视频的视频分辨率和纵横比?

c++ - 尝试使用初始化器列表来初始化类的成员值时出现编译错误

c++ - 如何在 Windows 下使用 C++ 在多个扬声器上播放声音?

c++ - 尝试编译 C++ 项目时出现 "unresolved external symbol"错误

c++ - 访问模板中的成员: how to check if the template is a pointer or not?

c++ - 如何在我的 Opensuse 中安装 qt 演示/示例?

qt - 无法将进度条扩展到状态栏的整个宽度