Qt QThread проблема с использованием сигнала / слота при переходе от рабочего к графическому интерфейсу - PullRequest
1 голос
/ 24 октября 2011

У меня есть приложение Qt, которое было разработано с использованием Qt Creator и сопровождающего его инструмента GUI. У меня есть основной поток TheGui и рабочий поток, созданный основным потоком WorkerThread (называемый thread).

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

public slot:
  void updateTable(string str);

в заголовочном файле GUI и сигнал void sendList(string str); в заголовочном файле рабочего потока, слот никогда не вызывается. Я соединил их, используя

connect(&thread, SIGNAL(sendList(string str),
        this,    SLOT(updateTable(string str)));

внутри конструктора в cpp-файле GUI. Я сделал что-то подобное, кроме слота в рабочем потоке и сигнала от графического интерфейса, и он работал нормально. Из использования отладчика я знаю, что сигнал sendList действительно вызывается, он просто никогда не входит в него.

Есть мысли?

Ответы [ 2 ]

4 голосов
/ 25 октября 2011
  1. Поскольку сигнал и слот находятся на разных потоках, соединение между ними имеет тип Qt::QueuedConnection. А для соединений с очередями Qt должен иметь возможность сохранить копию параметров сигнала, чтобы потом передать их в слот.
    Итак, чтобы сообщить Qt, что тип является копируемым, вы должны зарегистрировать его в мета-объектной системе Qt (см. QMetaType ) следующим образом:

    // This macro call should be put in one of your .h files 
    Q_DECLARE_METATYPE(std::string)
    
    // You should call this function before any (queued) 
    // signal/slot connection involving the type
    qRegisterMetaType<std::string>();
    
  2. Имя параметра не должно включаться в вызов QObject::connect, а имена типов должны точно совпадать с именами, которые вы передали Q_DECLARE_METATYPE:

    connect(&thread, SIGNAL(sendList(std::string), this, SLOT(updateTable(std::string)));
    

Вы также можете использовать QString или QByteArray, которые уже зарегистрированы, вместо std::string, поскольку эти функции являются слотами и сигналами и, как таковые, уже зависят от Qt.

1 голос
/ 25 октября 2011

Уверен, что соединение действительно установлено?Если есть какие-либо проблемы с вызовом подключения, обычно есть какие-то отладочные данные об этом на cerr.

Во-вторых, я думаю, что у вас есть опечатка - если вы скопировали вызов подключения из своего кода, то знайте, что выв SIGNAL отсутствуют круглые скобки - должно быть

connect(&thread, SIGNAL(sendList(string)), this, SLOT(updateTable(string)));

В-третьих, что вы передаете в качестве параметра сигнал / слот?Это std :: string?Соединения между потоками должны быть в очереди соединений.Подключения в очереди могут использовать в качестве параметров только типы, объявленные с помощью макроса Q_DECLARE_METATYPE и зарегистрированные с помощью qRegisterMetaType .Насколько я знаю, Qt по умолчанию не объявляет их для std::string, так как предпочитает QString.Если вы не добавили их в свой код, это может быть причиной сбоя.

...