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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: GUI-поток + (поток + msleep) - засыпает всё  (Прочитано 4503 раз)
yegoriy
Гость
« : Июнь 27, 2012, 18:30 »

   Работаю с потоками недавно и столкнулся с интересным поведением.
Есть класс основного потока:

Код:
class MainWindow : public QMainWindow
{
    Q_OBJECT

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

signals:
    void StartSomthingDo();

private slots:
    void on_pbStartThread_clicked();

private:
    Ui::MainWindow *ui;
    MyThread *TestThread;
};

и класс второстепенного потока:
Код:
class MyThread : public QThread
{
    Q_OBJECT

public:
    MyThread();

public slots:
    void StartDo();
};

Реализация выглядит примерно так:
Код:
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

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

MyThread::MyThread()
{

}

void MainWindow::on_pbStartThread_clicked()
{
    TestThread = new MyThread();
    connect(this,SIGNAL(StartSomthingDo()),TestThread,SLOT(StartDo()));
    TestThread->start();
    emit StartSomthingDo();
}

void MyThread::StartDo()
{
    msleep(5000);
}

Проблема заключается в следующем: метод msleep в второстепенном потоке вешает основной GUI-поток.
Собственно не могу понять из-за чего? Есть мысли по этому поводу?
Записан
alexis031182
Гость
« Ответ #1 : Июнь 27, 2012, 18:35 »

Странная реализация. QObject::moveToThread() забыли
Записан
Bepec
Гость
« Ответ #2 : Июнь 27, 2012, 18:53 »

Алексис, вы безусловно правы, но внимательнее всмотритесь Веселый

Класс унаследован от потока, НО метод run не переопределён.

Интересно, поток сразу умрёт, или нет? Счас попробую аж Веселый

Записан
alexis031182
Гость
« Ответ #3 : Июнь 27, 2012, 18:57 »

Алексис, вы безусловно правы, но внимательнее всмотритесь Веселый
Класс унаследован от потока, НО метод run не переопределён.
Интересно, поток сразу умрёт, или нет? Счас попробую аж Веселый
Да я понял, потому и написал, что странная реализация Улыбающийся
Записан
yegoriy
Гость
« Ответ #4 : Июнь 27, 2012, 19:06 »

Метод run ,по докам, можно и не переопределять, он по-умолчанию содержит exec() - запускается цикл обработки событий. Сигнал пришёл - функция работает. В этом же вся прелесть модели сигнал-слот. Выход из потока quit() или exit(). Пример накидывал на коленках по-минимальному содержанию, посему выход и завершение потока не реализованы...
« Последнее редактирование: Июнь 27, 2012, 19:10 от yegoriy » Записан
alexis031182
Гость
« Ответ #5 : Июнь 27, 2012, 19:19 »

Если Вы наследуете QThread, то логично использовать переопределение run(). Если не наследуете, то логично использовать отдельный класс, функционал которого требуется выполнять в отдельном потоке.
Записан
Bepec
Гость
« Ответ #6 : Июнь 27, 2012, 19:22 »

Да кстати, вы правы, он по умолчанию запускает цикл Улыбающийся Это я знал, но не воспринимал Веселый Благодаря вам знаю.

У вас одна проблема - Ваш слот является лишь обычным методом класса. Чтобы он был в другом потоке, можно сделать 2 вещи:

1) сделать moveToThread(this) в конструкторе вашего класса-потока. (мой выбор.) Тогда нет нужды в 2 классах, но теряется гибкость переноса вашего класса в другой поток (а оно вам надо? Показает язык)

2) создать отдельный класс с этим слотом, далее создать QThreadName и сделать moveToThread(QThreadName). Выбор других людей на этом форуме, например alexis031182. Улыбающийся

Оба способа имеют свои преимущества и недостатки. Но они равноправны Веселый
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Июнь 27, 2012, 19:24 »

В очередной раз moveToThread. Слот вызывается в главной нитке, ну ее и вешает. Попечатайте currentThreadID в слоте чтобы убедиться
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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