Russian Qt Forum
Май 02, 2024, 11:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Сигнально-слотовое соединение потоков  (Прочитано 4144 раз)
juvf
Программист
*****
Offline Offline

Сообщений: 564


Просмотр профиля
« : Сентябрь 05, 2010, 20:26 »

Есть GUI поток и второй поток MyThread. Нужно обмениваться событиями между потоками. Решил через слоты-сигналы. В главном потоке генерирую сигнал, во втором потоке должен обрабатываться слот. Не получается. Взял готовый пример из "Макс Шлее - QT4.5. Профессиональное программирование на C++." (стр 618-621). Немножко подправил его: добавил кнопку, чтоб контролировать GUI поток.
Код:
#include <QtGui>

// ======================================================================
class MyThread : public QThread {
Q_OBJECT
private:
    int m_nValue;

public:
MyThread() : m_nValue(10){}

void run(){exec();}

signals:
void finished();
    void currentValue(int);

public slots:
    void slotNextValue()
    {
        emit currentValue(--m_nValue);

if (!m_nValue)
{
            emit finished();
        }
while(1) usleep(100);
       
    }
};

// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QLCDNumber   lcd;
QPushButton *button = new QPushButton(QString("Button"));
    MyThread     thread;

QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), &thread, SLOT(slotNextValue()));
timer.start(1000);



    QObject::connect(&thread, SIGNAL(currentValue(int)),
                     &lcd,    SLOT(display(int))
                    );
    QObject::connect(&thread, SIGNAL(finished()),
                     &app,    SLOT(quit())
                    );

    lcd.setSegmentStyle(QLCDNumber::Filled);
    lcd.display(10);
    lcd.resize(220, 90);
QWidget widget;
QHBoxLayout *layout = new  QHBoxLayout;
layout->addWidget(&lcd);
layout->addWidget(button);
widget.setLayout(layout);
widget.show();
    thread.start();
 
    return app.exec();
}

#include "main.moc"

Таймер в основном потоке генерирует сигнал и в потоке MyTread должен быть вызван слот slotNextValue(). Чтоб проверить в каком из потоков вызывается слот решил слот подвесить, добавив строку while(1) usleep(100). Попадая в slotNextValue  GUI поток виснет, т.е. получается что слот обрабатывается в главном потоке. Как сделать чтоб сигнал из GUI потока вызывал слот во втором потоке?

Пробовал сделать соединенеи
 QObject::connect(&timer, SIGNAL(timeout()), &thread, SLOT(slotNextValue()), Qt::QueuedConnection);
или
QObject::connect(&timer, SIGNAL(timeout()), &thread, SLOT(slotNextValue()), Qt::DirectConnection);
не помогает. Gui также виснит.

Записан
BRE
Гость
« Ответ #1 : Сентябрь 05, 2010, 20:29 »

Код
C++ (Qt)
// ======================================================================
class MyThread : public QThread
{
...
MyThread() : m_nValue(10) { moveToThread( this ); }
...
 

И не каких DirectConnection.
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 564


Просмотр профиля
« Ответ #2 : Сентябрь 06, 2010, 09:30 »

Спасибо, проблема решена
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.092 секунд. Запросов: 22.