Как подключить сигнал от нити к слоту?

0

То, что я просто хочу сделать, это подключить сигнал внутри потока к слоту в основном потоке для обработки изменений пользовательского интерфейса.

Это в основном текущее состояние моей нити, ничего необычного, но это просто для целей тестирования atm:

// synchronizer.h
class Synchronizer : public QObject
{
    Q_OBJECT

public:
    Synchronizer();

signals:
    void newConnection(std::wstring id);

private:
    QTimer timer;

private slots:
    void synchronize();
}

// synchronizer.cpp
Synchronizer::Synchronizer()
{
    connect(&timer, SIGNAL(timeout()), this, SLOT(synchronize()));
    timer.start();
}

void Synchronizer::synchronize()
{
    emit newConnection(L"test");
}

И вот, как выглядит мой MainWindow:

// mainwindow.h
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    Synchronizer synchronizer;

private slots:
    void addConnection(std::wstring id);
}

// mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(&synchronizer, SIGNAL(newConnection(std::wstring)),
            this, SLOT(addConnection(std::wstring)));
    QThread *thread = new QThread;
    // The problems starts here?
    synchronizer.moveToThread(thread);
    thread->start();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::addConnection(std::wstring id)
{
    // Add a new connection to QListWidget
    ui->connectionList(QString::fromStdWString(id));
}

Если я удалю там строки:

synchronizer.moveToThread(thread);
thread->start();

все выглядит так, как ожидалось, то есть новый элемент добавляется каждую секунду к QListWidget, но как только я перемещаю объект синхронизатора в поток, он просто перестает работать. Я предполагаю, что это имеет какое-то отношение к контексту подключения, но я не совсем уверен, как что-то подобное должно быть достигнуто, поскольку я совершенно новичок в Qt.

  • 0
    Вам, вероятно, нужно выполнить подключение после synchronizer.moveToThread (thread); или используйте параметр Qt :: QueuedConnection в соединении.
  • 0
    Я скопировал ваш код в свое приложение, и он работает нормально. Может я не правильно читаю вопрос?
Показать ещё 1 комментарий
Теги:
multithreading
qt

1 ответ

1
Лучший ответ

Похоже, что в этом случае я просто использовал std :: wstring в качестве аргумента в сигнале без регистрации типа first и после добавления следующей строки qRegisterMetaType<std::wstring>("std::wstring"); к коду все работало, как ожидалось.

Если бы я более внимательно прочитал выводную консоль, я бы решил проблему без лишних хлопот, поскольку было четко указано, что:
QObject::connect: Cannot queue arguments of type 'std::wstring'

Так что просто говоря, прочитайте вывод компилятора и не будьте глупыми, как я :)

  • 0
    Вы упомянули, что это работает, если вы прокомментируете moveToThread и начнете. Это была неверная информация, тогда?
  • 0
    Нет, это сработало, когда я закомментировал две строки, но в тот момент он не был в отдельном потоке и работал в том же (основном) потоке, что и объект MainWindow. Поэтому я предполагаю, что организация очереди аргументов применяется, когда вы пытаетесь передать аргумент из потока, и не нужна, когда вы работаете в том же потоке, что, скорее всего, приводит к простым вызовам локальных методов без какой-либо сложной очереди.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню