Мое приложение имеет 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 реагировали на клавиатуру и мышь?
Вы можете попробовать позвонить QCoreApplication::processEvents()
периодически во время обработки этих событий окна.
Вам нужно либо профилировать этот код и ускорить его, чтобы он не блокировал цикл обработки событий, либо вам нужно запустить этот код в отдельном потоке.
Для профилирования я рекомендую взглянуть на 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();
}