Qt - 计时器只能与使用QThread启动的线程一起使用。

8

我的代码是

class ExampleTest : public QObject
{
    Q_OBJECT

public:
    ExampleTest() {}

private Q_SLOTS:
   void DoAllExampleTests();
};

void ExampleTest::DoAllExampleTests()
{
    QProcess p;

    p.start( "cmd /c wmic path Win32_usbcontrollerdevice|grep VID_1004" );
    qDebug() << "Here 1";
    QVERIFY( TRUE == p.waitForFinished() );
    qDebug() << "Here 2";
}

QTEST_APPLESS_MAIN(ExampleTest);

我在Here 1和Here 2之间收到了一个警告。
QObject::startTimer: Timers can only be used with threads started with QThread

我从QObject :: startTimer:Timers can only be used with threads started with QThread这篇文章中学到,当我子类化一个Qt类且子类的某个成员不是Qt层次结构的一部分时,会发生此警告。我有一个从QObject继承的ExampleTest类,但仍然收到警告。如何避免此警告?

1个回答

15
警告信息可以用更好的措辞来表述——这不完全是一个 QThread 的问题,而是一个事件循环问题。QThread 会自动为您设置一个事件循环,但在这里,您只有一个主线程。
有两种方法可以在主线程中创建一个事件循环:
  1. 使用 QEventLoop 手动创建
  2. 使用 QApplication(或其子类)自动创建
大多数应用程序将使用选项 2。然而,您正在编写一个单元测试。您的单元测试能够在没有 QApplication 的情况下运行,是因为您指定了 QTEST_APPLESS_MAIN。引用 文档 中的话:

实现一个 main() 函数,用于执行 TestClass 中的所有测试。

与 QTEST_MAIN() 类似,但不会实例化 QApplication 对象。对于非常简单的独立非 GUI 测试,请使用此宏。

重点在于“不会实例化 QApplication 对象”。
所以,您只需要将最后一行改为:
QTEST_APPLESS_MAIN(ExampleTest);

转换为:

QTEST_MAIN(ExampleTest);

...那应该解决问题。


然后使用 make check TESTARGS="-platform offscreen" 运行 QTest,并从 .pro 项目文件中删除 QtCreator 为您放置的 QT -= gui 行。如果您正在使用 SUBDIRS 样式的单元测试项目,则需要将所有子项目更改为 QTEST_MAIN,以应对 -platform 命令行参数。 - Mark Ch
对于不链接 QtGui 库的应用程序,可以使用 QTEST_GUILESS_MAIN。它介于 QTEST_APPLESS_MAIN 和 QTEST_MAIN 之间。 - textshell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接