通过信号/插槽机制将 QString 传递给 QThread

Passing QString to QThread through Signal/Slot mechanism

本文关键字:QString QThread 机制 信号 插槽      更新时间:2023-10-16

我在让我的主窗口与工作线程通信时遇到问题。我正在使用通常的信号/插槽机甲传递 QString 对象。我的程序应该将QString"Alice"从MainWindow转移到在QThread中处理的类Workers的worker对象,然后再返回。代码编译没有错误,在我的MacBook Pro上使用Qt 4.8和Clang运行。这是显示我问题的最小代码。

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <worker.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    void ThreadedWork();
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    QString name;
private slots:
    void errorString(QString);
public slots:
    void getFromWorker(QString);
signals:
    void sendToWorker(QString);
};
#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    name = "Alice";
    qDebug() << "The name in MainWindow is: " << name << " from ThreadID = " << QThread::currentThreadId();
    ThreadedWork();
    qDebug() << "Name sent from the Worker Thread is: " << name;
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::errorString(QString string)
{
    qDebug() << "The error from the threaded process is: " << string;
}
void MainWindow::ThreadedWork()
{
    Worker* worker = new Worker;
    emit sendToWorker(name);
    connect(this,SIGNAL(sendToWorker(QString)),worker,SLOT(getFromMain(QString)));
    connect(worker,SIGNAL(sendToMain(QString)),this,SLOT(getFromWorker(QString)));
    QThread *thread = new QThread;
    worker->moveToThread(thread);
    connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
    connect(thread, SIGNAL(started()), worker, SLOT(process()));
    connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    thread->start();
}
void MainWindow::getFromWorker(QString someName) //slot implementation
{
    name = someName;
}

工人.h

#ifndef WORKER_H
#define WORKER_H
#include <QObject>
class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(Worker * parent = 0);
    ~Worker();
signals:
    void sendToMain(QString);
    void error(QString err);
    void finished();
public slots:
    void getFromMain(QString);
    void process();
private:
    QString name;
};
#endif // WORKER_H

工人.cpp

#include "worker.h"
#include <QDebug>
#include <QThread>
Worker::Worker(Worker * parent)
{
}
Worker::~Worker()
{
}
void Worker::process() {
    // allocate resources using new here
    qDebug() << "name recieved from Main is: " << name;
    qDebug() << "name passed to Worker Thread is: " << name << " having ThreadID = " << QThread::currentThreadId();
    emit sendToMain(name);
    emit finished();
}
void Worker::getFromMain(QString someName) // slot implementation
{
    name = someName;
}

我的输出是:

The name in MainWindow is:  "Alice"  from ThreadID =  0x7fff7de7a300 
Name sent from the Worker Thread is:  "Alice" 
name recieved from Main is:  "" 
name passed to Worker Thread is:  ""  having ThreadID =  0x1107a9000

如上所述,我无法将QString"Alice"传递给工人。我在这里错过了什么?

ThreadedWork()方法的问题:

您首先发出信号emit sendToWorker(name);,只有他们将这个连接到插槽 - 这是您失败的根源。

像这样更改行:

void MainWindow::ThreadedWork()
{
    Worker* worker = new Worker;
    connect(this,SIGNAL(sendToWorker(QString)),worker,SLOT(getFromMain(QString)));
    connect(worker,SIGNAL(sendToMain(QString)),this,SLOT(getFromWorker(QString)));
    emit sendToWorker(name);
    QThread *thread = new QThread;
    worker->moveToThread(thread);
...
}

我可能得到预期的结果:

The name in MainWindow is:  "Alice"  from ThreadID =  0xcbc
Name sent from the Worker Thread is:  "Alice"
name recieved from Main is:  "Alice"
name passed to Worker Thread is:  "Alice"  having ThreadID =  0xff8