我有两个问题:
-
我如何访问
QFileDialog
并使用Qt测试模块在"文件名"字段中写入文件的路径?我问,因为我在Qt开发一些GUI测试,现在我需要打开一个文本文件。下面的代码创建
QFileDialog
并获取文件路径:QString filePath = QFileDialog::getOpenFileName( this, "Open", "", tr("Text Files (*.txt)") );
-
如果我使用一个线程(
QThread
)来加载这个文本文件中的内容,我怎么能等待这个线程在我的GUI测试中完成?我知道我可以使用
QTest::qSleep( milliseconds );
命令,但我不认为这是一个很好的做法,在这种情况下
如果可能的话,请给我举个例子。
-
不幸的是,这是不可能使用Qt测试模块。您有几个选择:
-
添加绕过该对话框的测试钩子:您需要测试代码以使其可测试。例如,你可以在请求文件的对象上设置
testFile
属性到文件路径,如果设置了该属性,对象可以跳过请求文件。const char k_testFile[] = "k_testFile"; MyClass::foo() { ... auto testFile = property(k_testFile); auto filePath = testFile.isNull() ? QFileDialog::getOpenFilePath(...) : testFile.toString(); ... }
-
使用一个非本地对话框,然后它是一个正常的小部件,你可以使用Qt测试。
-
使用特定于平台的方法来查找本机对话框并与之交互。
-
-
应该在文件加载后发出一个信号。测试可以等待这个信号。您甚至不需要使用显式线程来加载文件,异步加载文件的惯用方法是:
调用这段代码的类应该有一个QString filePath = ...; QtConcurrent::run(ioPool, [this, filePath]{ auto data = MyLoader::load(filePath); emit haveFileData(data); });
haveFileData
信号,其他代码可以连接到这个信号并按预期进行。ioPool
是用于I/O绑定操作的线程池,如果您希望全局池作为I/O池,它可以是QThredPool::globalInstance()
。CPU绑定线程池和I/o绑定线程池应该分开。