Как сохранить Qt Widgets чувствительными к клавиатуре и мыши при обработке событий Windows?

Мое приложение имеет QLineEdit и QPushButton которые не реагируют должным образом на вводы клавиатуры и мыши ( QLineEdit не получает ввод с клавиатуры, и оба QLineEdit а также QPushButton не получают данные от мыши), когда мое приложение обрабатывает эти события Windows:

bool MainWindow::winEvent(MSG *msg, long *result)
{
HWND hWnd = msg->hwnd;
UINT message = msg->message;
WPARAM wParam = msg->wParam;
LPARAM lParam = msg->lParam;

bool retval = true;
LRESULT lRet = 0;

switch(message)
{
case WM_PAINT:
{
HDC hDC = GetWindowDC(hWnd);
PaintCustomCaption(hWnd, hDC); //Method responsible to draw the image at the non client area
DeleteDC(hDC);
break;
}
case WM_NCHITTEST:
{
lRet = HitTestNCA(hWnd, lParam); //Method responsible to deal with the window resizing and moving
DwmDefWindowProc(hWnd, message, wParam, lParam, &lRet);
break;
}
case WM_NCCALCSIZE:
{
break;
}
default:
{
retval = false;
DwmDefWindowProc(hWnd, message, wParam, lParam, &lRet);
break;
}
}

*result = lRet;
if(retval) return true;

return QWidget::winEvent(msg, result);
}

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

Можно ли обрабатывать события Windows, перечисленные выше, чтобы мои виджеты Qt реагировали на клавиатуру и мышь?

0

Решение

Вы можете попробовать позвонить QCoreApplication::processEvents() периодически во время обработки этих событий окна.

2

Другие решения

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

Для профилирования я рекомендую взглянуть на valgrind, callgrind и kcachegrind.

Что касается потоков, большинство приложений Qt являются однопоточными по умолчанию, поэтому, если вы не вернете обработку обратно в цикл событий достаточно быстро, события пользовательского интерфейса будут засоряться в цикле событий и не будут обрабатываться, пока вы не вернете обработку к событию петля.

Создать новые темы довольно просто в Qt. Посмотрите этот пример из документации Qt на QThread:

void MyObject::putWorkerInAThread()
{
Worker *worker = new Worker;
QThread *workerThread = new QThread(this);

connect(workerThread, &QThread::started, worker, &Worker::doWork);
connect(workerThread, &QThread::finished, worker, &Worker::deleteLater);
worker->moveToThread(workerThread);

// Starts an event loop, and emits workerThread->started()
workerThread->start();
}
1