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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает  (Прочитано 12183 раз)
Caduceus
Гость
« : Сентябрь 02, 2009, 21:39 »

Все дело под Windows.
Есть формочка с кучей кнопок, контролов. И есть один виджет, который явлется просто указателем места, над которым я создаю свое окно. Причем окно это создается в другом потоке. Родитель этого окна - то что возвращает этот виджет через winId. Окно создает, все нормально работает. Но: все конролы на форме недоступны, то есть видны, но не нажимаются. И сразу после того, как я пытаюсь запустить Spy++, вываливается ошибка, что QAppication шлет евент объекту, созданному в другом потоке.

Вот такая штука. Запустался уже.  Что это может быть?
« Последнее редактирование: Сентябрь 02, 2009, 21:42 от Caduceus » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #1 : Сентябрь 02, 2009, 22:09 »

нельзя создавать окна в потоке, отличном от главного
Записан
Caduceus
Гость
« Ответ #2 : Сентябрь 02, 2009, 22:12 »

если я создаю окно в главном потоке, то весь цикл обработки его сообщений гасит вообще все - весь главный ГУИ просто умирает и не отрисовывается, не то что отвечать на нажатия
Записан
ufna
Гость
« Ответ #3 : Сентябрь 02, 2009, 22:25 »

значит, нужно что то модифицировать. Опиши поподробней, что делает это окно.
Записан
Caduceus
Гость
« Ответ #4 : Сентябрь 02, 2009, 22:28 »

Это второе окно - прикрученный к Qt-шной проге игровой движок.
В нем все хорошо там крутиться. На события мыши и клавы реагирет. А вот Qt-шный GUI не нажимается.
Более того, если внутрь второго окна не нажмать, то Qt-шное таскается и ресазиться, а если по второму окну кликнуть (там анимация проигрывается), то qt-ное окно перестает отвечать на сдивги за заголовок и ресайзы за уголки. Надо щелкнуть вообе на другуое приложние, потом щелкуть на qt-шное окно — и вот огда оно реагирует на перемещения и ресайзы, хотя контролы все равно не нажимаются
Записан
BlackTass
Гость
« Ответ #5 : Сентябрь 03, 2009, 00:57 »

Почему бы не пробрасывать обработку в отдельный тред, откуда она тоже соответственно будет пробрасываться обратно на отрисовку?
Записан
Caduceus
Гость
« Ответ #6 : Сентябрь 03, 2009, 08:43 »

Все что касается этого нативного окна и так в отдельном потоке. Вопрос немного перефразирую - не отслеживает ли Qt все дочерние окна (даже если они не qt шные а наивные) и не рулит ли как-то их циклом обработки сообщений сам?
Записан
Tonal
Гость
« Ответ #7 : Сентябрь 03, 2009, 10:23 »

Я уже на rsdn-е ответил: во втором потоке нужен свой цикл выборки сообщений.
Записан
Caduceus
Гость
« Ответ #8 : Сентябрь 03, 2009, 10:44 »

Так там он, там. Во втором потоке
Записан
BlackTass
Гость
« Ответ #9 : Сентябрь 03, 2009, 11:11 »

если в главном потоке обработка событий сводится к эмитам и при этом умирает гуй, то сколько же там валится событий?
Записан
Caduceus
Гость
« Ответ #10 : Сентябрь 03, 2009, 11:16 »

Игровой движок, можно представить что там куча всего.
НО! есть одно НО. Я делал те же самые действия, то только через ActiveX - то есть я создавал ATLный ActiveX - в нем над окном Конрола создавал во втором потоке окно движка и ВСЕ суперско работало. Я кидал этот контрол на C#-ную форму и все зашибись

Сейчас я это дело перевел на Qt - то есть создаю окно движка надQt виджетом - и все кроме движка засыпает...

Продебажил конкретно вглубь Qt - при нажатии на конролы он даже в QtWndProc не заходит. Кто-то конкретно перехватывает это все дело.
« Последнее редактирование: Сентябрь 03, 2009, 13:16 от Caduceus » Записан
BlackTass
Гость
« Ответ #11 : Сентябрь 03, 2009, 13:40 »

там ваших собственных событий куча или каких? если ваших собственных смело кидайте их в другой поток да и все. У вас точно во втором потоке eventLoop работает в этом самом втором потоке, а не в гуевом?
Записан
Caduceus
Гость
« Ответ #12 : Сентябрь 03, 2009, 13:43 »

моих сообщений там вобще никаких нету. Цикл нативного окна 100% во втором потке.
Всё, уже не знаю куда копать. Все перепробовал
Записан
BlackTass
Гость
« Ответ #13 : Сентябрь 03, 2009, 13:45 »

ну так как libastral и телепатия пока еще только развиваются, я думаю стоит выложить исходники (желательно обрезанные до самого минимума).
Записан
Caduceus
Гость
« Ответ #14 : Сентябрь 03, 2009, 14:01 »

О, получилось воспроизвести без игрового движка. Короче, есть наиримитвнейшая формочка с двумя кнопками и кастомным виджетом. При нажатии на кнопку кастомному виджету шлтеся сигнал. Вот функция слота:

Код:
void   EngineWidget::StartEngine()
{
if (m_hThread)
return;
DWORD    dwThreadId      = -1;
if ((m_hThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadFunc,
(LPVOID)this, 0, &dwThreadId)) != NULL)
{
;
}
}

Примитивно? Примитивно. А сейчас вот самое интересное - потоковая функция threadFunc:
Код:
static DWORD WINAPI threadFunc(LPVOID pWidg)
{  
     QWidget* wdt = (QWidget*)pWidg;

WNDCLASSEX windowClass;
HINSTANCE engineInstance;
HWND engineWindow;

HINSTANCE h = ::GetModuleHandle(QApplication::applicationFilePath().toAscii());

windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_NOCLOSE | CS_OWNDC;
windowClass.lpfnWndProc = &DefWindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = engineInstance;
windowClass.hIcon = nullptr;
windowClass.hCursor = LoadCursor(nullptr, IDC_ARROW);
windowClass.hbrBackground = nullptr;
windowClass.lpszMenuName = nullptr;
windowClass.lpszClassName = APPLICATION_NAME;
windowClass.hIconSm = nullptr;
RegisterClassEx(&windowClass);

// RA changes
engineWindow = CreateWindow(APPLICATION_NAME, APPLICATION_NAME, WS_CHILD|WS_VISIBLE, 0, 0, 1280, 1024, (HWND)wdt->winId(),
nullptr, h, nullptr);

// RA changes
SetFocus(engineWindow);
SetCursor(windowClass.hCursor);

do
{

MSG message;

while (PeekMessage(&message, engineWindow, 0, 0, PM_REMOVE))
{
DispatchMessage(&message);
}
}while(true);
return FALSE;
}

Во. Вот если так сделать - то все кнопки на qt-шной форме перестают нажиматься. Это я в очень приближенной форме написал как работает окно игрового движка. Разумеется там не DefWindowProc оконная функция, но и так уже виснет.

Кто что думает?

PS Предвижу сразу фразы типа "Ага, у тебя нативное окно прям поверх всего делается из угла окна - кординаты 0 -0". Отвечу - опускал я это окно, было оно точно под кнопками, то есть кнопки не перекрывало - но они все равно не нажимались
« Последнее редактирование: Сентябрь 03, 2009, 14:07 от Caduceus » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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