Qt 4.7+ сбой Xlib в методе QWidget::winId()
Извините за мой английский, но у меня есть следующая проблема. Я пишу оконный менеджер, используя Qt 4.7 и Xlib. У меня есть менеджер класса, который наследует QApplication и переопределенный метод X11EventFilter в нем. В методе X11EventFilter я ловлю необходимые события из XServer. Когда я получаю событие MapRequest, я улавливаю появление нового окна и перезаписываю его в свой собственный виджет. И когда я создаю этот виджет и вызываю методы QWidget::show() или QWidget::winId(), происходит сбой программы. В чем проблема?
Вот метод, где создается виджет. Интересно, когда эта функция вызывает несколько раз при запуске программы, все в порядке.
void Manager::createClientWindow(Qt::HANDLE pWinID)
{
QMWindowWidget *lWindowWidget = new QMWindowWidget(pWinID);
/*some code*/
lWindowWidget->show();//crash is here
Qt::HANDLE widgetId = lWindowWidget->winId();//and here
/*some code*/
}
Вот метод x11EventFilter, где вызывается функция createClientWindow
bool Manager::x11EventFilter(XEvent *pEvent)
{
switch(pEvent.type)
{
/*some code*/
case MapRequest:
{
Qt::HANDLE lWindow = pEvent->xmaprequest.window;
QMWindowWidget* lWidget = findWidget(lWindow);
if (!lWidget)
{
lWidget = dynamic_cast<QMWindowWidget*>(QWidget::find(lWindow));
}
if (lWidget)
{
XMapWindow(QX11Info::display(), lWindow);
lWidget->show();
XRaiseWindow(QX11Info::display(), lWidget->winId());
return true;
}
else
{
createClientWindow(lWindow);//here is where function is called
return true;
}
}
break;
/*some code*/
} //switch
return false;
}
2 ответа
Проблема решена! Я вставляю эти две строки перед QApplication::exec()
XClearWindow(QX11Info::display(), QX11Info::appRootWindow());
XSync(QX11Info::display(), false);
Проблема, скорее всего, заключается в коде, представленном /*some code*/
, Поскольку неизвестно, что там, очень трудно точно определить точную причину проблемы. Если вы не можете показать весь код, вам придется самостоятельно отследить проблему.
Вам нужно будет собрать в режиме отладки и связать с отладочной версией Qt. Затем, когда происходит сбой, посмотрите на точную строку источника Qt, проанализируйте поврежденные структуры данных с помощью отладчика и попытайтесь выяснить, почему они повреждены. Может быть, установить точку наблюдения для проблемной переменной и выяснить, какой код записывает туда недопустимое значение.
Чтобы программировать на языках низкого уровня, таких как C и C++, нужно научиться делать это.