现在我想创建一个线程并将我的类放入“AVC_file”inatance。
但是当我在textBroswer中打印currentThreadId时,我发现MainWindows的threadID与我创建的线程相同。显示如下的情况。
Framework::Framework(QWidget * parent) : QMainWindow(parent)
{
ui.setupUi(this);
int threadID = (int)QThread::currentThreadId();
ui.textBrowser->append("Main Tread ID : " + QString::number(threadID));
}
void Framework::on_OpenAVCFile_clicked()
{
QString filePath = QFileDialog::getOpenFileName(
this, tr("Open File"), "C:\\", "AVC File (*.avc)"
);
if (!filePath.isEmpty())
{
QMessageBox::information(this, tr("File Name"), filePath);
}
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly))
{
QMessageBox::information(0, "info", file.errorString());
}
else {
QThread *thread = new QThread(this);
int threadID = (int)thread->currentThreadId();
ui.textBrowser->append("Second Tread ID : " + QString::number(threadID) + "\n");
AVC_File *AVC_file = new AVC_File();
AVC_file->moveToThread(thread);
connect(AVC_file, SIGNAL(requestFileContent(QString)), this, SLOT(addFileContent(QString)));
connect(AVC_file, SIGNAL(requestFileDebug(QString)), this, SLOT(addFileDebug(QString)));
connect(AVC_file, SIGNAL(requestFileCorrectness(bool, int)), this, SLOT(adddFileCorrectness(bool, int)));
connect(AVC_file, SIGNAL(requestNewValue(unsigned int, int)), this, SLOT(addNewValue(unsigned int, int)));
thread->start();
AVC_file->AVC_FileCheck(file);
}
}
关于我的代码和结果的图片 - > Main Windows, create thread and results
哦!我也尝试在我的“AVC_file”实例中发出信息?如下所示。
void AVC_File::AVC_FileCheck(QFile &file)
{
int threadID = (int)QThread::currentThreadId();
emit requestFileContent("Thread ID by emit" + QString::number(threadID) + "\n");
QTextStream in(&file);
........
........
}
任何人都可以帮助我?
BTW,我使用visual studio Qt插件来开发这个项目。
答案 0 :(得分:5)
QThread::currentThreadId()
是一种静态方法。
当你调用它时,它会返回执行它的线程的线程ID。
在你的两个案例中都是主线程。
答案 1 :(得分:2)
我将按随机顺序解决几个问题。
首先,使用线程ID是糟糕的用户体验。为线程提供一个描述性名称:
int main(...) {
QApplication app(...);
QThread myThread;
MyObject myObject;
myObject->moveToThread(&myThread);
QThread::currentThread()->setObjectName("mainThread");
myThread.setObjectName("myThread");
...
}
然后使用QThread::currentThread()->objectName()
检索它。您还可以将QObject*
传递给qDebug()
以显示该主题的名称:
qDebug() << QThread::currentThread();
您的信号调用将变为:
QString currentThreadName() {
return QThread::currentThread()->objectName().isEmpty() ?
QStringLiteral("0x%1").arg(QThread::currentThread(), 0, 16) :
QThread::currentThread()->objectName();
}
...
emit requestFileContent(
QStringLiteral("Emitting from thread \"%1\"\n").arg(currentThreadName));
然后,使用上面的内容来处理你创建的主题:
auto thread = new QThread(this);
thread->setObjectName("fileThread");
ui.textBrowser->append(QStringLiteral("Worker thread: \"%1\").arg(thread->objectName()));
auto AVC_file = new AVC_File;
AVC_file->moveToThread(thread);
...
但是从主线程调用AVC_FileCheck
。是否可以取决于该方法的实现方式。它需要是线程安全的,请参阅this question进行讨论。 TL; DR:以下模式可以作为起点:
class AVC_file : public QObject {
Q_OBJECT
Q_SLOT void fileCheck_impl(QIODevice * dev) {
dev->setParent(this);
...
}
Q_SIGNAL void fileCheck_signal(QIODevice *);
public:
void fileCheck(QIODevice *dev) { fileCheck_signal(dev); }
AVC_file(QObject *parent = nullptr) : QObject(parent) {
connect(this, &AVC_file::fileCheck_signal, this, &AVC_file::fileCheck_impl);
...
}
};
最后,您现有的AVC_fileCheck
API已损坏。您通过引用传递QFile
:这将永远不会起作用,因为on_OpenAVCFile_clicked
返回后它就不再存在。当AVC_file
在其线程中使用该文件时,它是一个悬空对象引用。
相反,您必须将文件的所有权传递给AVC_file
,并将指针传递给AVC_file
完成时将处置的实例。或者只需让AVC_file
为您打开文件!