QWinWidget Inside MFC Dialog Not Repainting or Responding to Tab/Arrow keys

陌路散爱 提交于 2019-12-10 21:40:51

问题


I am using a QWinWidget inside of an MFC dialog and the QWinWidget is not drawing itself correctly and it is not handling keyboard input correctly.

Repainting [Unsolved]

Within the QWinWidget, I have a QTableWidget. When I scroll the QTableWidget, it does not redraw itself until I stop scrolling, at which point it redraws everything. Similarly, I can type into cells in the QTableWidget and the control is not updated until I force it to re-update by scrolling up or down (it re-updates when the scrolling stops).

Since this QWinWidget is housed in an MFC CDialog, I tried overriding the CDialog's OnPaint method and only call the QWinWidget::repaint method, however this has the opposite problem where now only the QWinWidget is updated and the CDialog is never redrawn, resulting in artifacts. If I call QWinWidget::repaint and CDialog::OnPaint, the result is the same as not overriding the OnPaint method. Has anyone ever seen this problem or know how to resolve it?

Keyboard Input [Solved]

None of the controls within the QWinWidget respond to the tab key or arrow keys correctly. The tab/arrow keys simply skip over the entire QWinWidget (and all child controls). Even if I click inside the QWinWidget and select a control, the next time I press the tab key, it skips the focus completely out of the entire QWinWidget.

I noticed that the QWinWidget has two functions, QWinWidget::focusNextPrevChild and QWinWidget::focusInEvent and both of them have a comment header saying "\reimp". Am I supposed to override these functions in order to get correct tab functionality? If so, how can these functions be implemented for correct tab functionality.


回答1:


I have fixed the keyboard input issue. The QWinWidget class needed some changes:

in the QWinWidget::init method, the WS_TABSTOP must be added to the window style:

SetWindowLong(winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP);

Also, the QWinWidget::winEvent method needs to respond to the WM_GETDLGCODE to let Windows know that it is interested in receiving key/tab inputs. I had to add this if block:

if(msg->message == WM_GETDLGCODE)
{
   *result = DLGC_WANTARROWS | DLGC_WANTTAB;
   return(true);
}

I am still working on getting the widget to paint properly.




回答2:


I don't know about whether you need to reimplement the focusNextPrevChild() and focusInEvent() functions, but I do know that the "\reimp" in the comment header is part of Qt's documentation generation, which merely specifies that the function was a reimplementation of another function in a parent class.




回答3:


No idea about the keyboard input, but concerning the repainting: have you tried calling QWinWidget::repaint() in the CDialog's OnPaint method AFTER calling the CDialog::OnPaint()?




回答4:


Thanks! It works for me! I have fixed an arrow keys navigation issue for a QTableView inside a QWinWidget. I am using Qt5.3.0 and qtwinmigrate 2.8. The QWinWidget::nativeEvent method needs to be modified.

#if QT_VERSION >= 0x050000
bool QWinWidget::nativeEvent(const QByteArray &, void *message, long *result)
#else
...
{
    ...
    if (msg->message == WM_SETFOCUS) {
        ...
    } else if (msg->message == WM_GETDLGCODE) {
        *result = DLGC_WANTALLKEYS;
        return true;
    }

    return false;
}


来源:https://stackoverflow.com/questions/1066183/qwinwidget-inside-mfc-dialog-not-repainting-or-responding-to-tab-arrow-keys

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!