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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Виснет диалог при отрисовке, а в GUI ли я потоке?  (Прочитано 3392 раз)
Fynjisx
Гость
« : Февраль 15, 2018, 12:59 »

Привет ВСем! Итак вопрос такой: Есть класс, в полях которого есть указатель на объект наследник от QDialog. Я создаю обьект основного класса, в конструкторе этого класса я создаю обьект в динамической памяти - указатель на наследника QDialog. Обьеект оснновного класса далее я перевожу из GUI потока в другой. Обьект в поле основного класса который я создал динамически в его конструкторе, остается в GUI потоке. Почему при вызове exec у наследника QDialog создается форма диалоога и все виснет?
Код:
Base.h
class Base
{
  public:
  Base();

  private:
  QDeriveDialog* m_DeriveDialog;

}
Base.cpp:
Base::Base
{
m_DeriveDialog = new QDeriveDialog();
}
...
в основной программе:
qDebug() << thread();      // запомним поток GUI
QThread thr = new QThread;
Base* base = new Base;
base->moveTothread(thr);
...
Base.cpp:
void process()
{
   qDebug() << m_DerivedDialog->thread;   // проверяю к какому потоку принадлежит объект
                                          // и он равен потоку GUI,
   if(m_DerivedDialog->exec() == QDialog::Rejected) // однако при вызове диал.окна, в нем
                                                    // все виснет, окно появляется только контуром,
                                                    // все остальное не прорисовывается и курсор в
                                                    // колесико превращается
      ret = false;
...
}
Обратите внимание что объект m_DerivedDialog продолжет принадлежать основному потоку GUI, но диалог на отрисовке зависает
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #1 : Февраль 15, 2018, 14:52 »

А process() в каком потоке вызывается? Возможно нужно проверить, может ли QDialog::exec() вызываться в потоке отличном от его thread или GUI-потока.
Записан

Пока сам не сделаешь...
Fynjisx
Гость
« Ответ #2 : Февраль 15, 2018, 15:20 »

А process() в каком потоке вызывается? Возможно нужно проверить, может ли QDialog::exec() вызываться в потоке отличном от его thread или GUI-потока.
Извините, я новичок. Что значит process() в каком потоке?
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #3 : Февраль 15, 2018, 15:44 »

С помощью QThread::currentThread() можно узнать текущий поток, в котором выполняется функция. Соответственно, в process() можно дописать:
Код
C++ (Qt)
void process()
{
  qDebug() << QThread::currentThread();
  qDebug() << m_DerivedDialog->thread;
  ...
}
и узнать, в каком потоке она вызвана. Возможно, process() вызывается где-нибудь в методе объекта base, который выполняется в своём потоке.

То, что m_DerivedDialog->thread при вызове process() равен GUI-потоку, может не значить, что m_DerivedDialog->exec() будет работать в GUI-потоке. Сейчас я точно не могу сказать, в чём там проблема, надо разбираться детальнее. Возможно, m_DerivedDialog->exec() нужно вызывать только в  GUI-потоке, и при вызове этого метода из другого потока происходит зависание.
Записан

Пока сам не сделаешь...
Fynjisx
Гость
« Ответ #4 : Февраль 15, 2018, 17:55 »

и узнать, в каком потоке она вызвана.
process() вызывается в потоке отличном от GUI, т.е я создал объект, в котором process() является методом этого обьекта, далее объект перетащил в другой поток.
Возможно, process() вызывается где-нибудь в методе объекта base, который выполняется в своём потоке.
да, так и есть...
То, что m_DerivedDialog->thread при вызове process() равен GUI-потоку, может не значить, что m_DerivedDialog->exec() будет работать в GUI-потоке.
А вот это интересно. Этой фишки не знал.

« Последнее редактирование: Февраль 15, 2018, 17:59 от Fynjisx » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 574


Просмотр профиля
« Ответ #5 : Февраль 16, 2018, 08:42 »

Нужно понять одну вещь. Объекты не принадлежат какому либо потоку, есть только сопоставление объекта потоку, в котором будут обрабатываться его события. Прямой вызов метода будет происходить всегда в текущем потоке.
Сопоставление объекту любого другого потока не каким волшебным образом не заставит прямые вызовы производить в потоке отличном от текущего.

Все объекты GUI должны быть связаны с тем потоком, в котором создан QApplication, обычно это главный поток.
При этом и любые вызовы методов GUI объектов должны производиться в этом же потоке. В противном случае поведение программы непредсказуемо.
Все это расписано в документации.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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