如何避免模态QDialog拦截QCompleter的鼠标事件?
解决模态QDialog中QCompleter弹出框鼠标事件被拦截的问题
模态QDialog调用exec()时,其事件循环会拦截所有不属于自身窗口层级的鼠标操作。QCompleter的弹出框默认是独立的顶级窗口,不属于模态对话框的子窗口树,因此会被判定为对话框外部区域,导致鼠标点击被拦截并触发系统警告音;而show()非模态显示时,对话框不会限制外部窗口的事件处理,所以功能正常。
解决方案
核心是将QCompleter的弹出框设置为模态对话框的子窗口,使其纳入对话框的事件处理范围:
QStringList user_list; user_list << "Tom" << "Jerry" << "John" << "Jack" << "Bob" << "Bobby" << "Amir" << "James" << "Carl"; auto completer_model = new QStringListModel(this); completer_model->setStringList(user_list); auto completer = new QCompleter(completer_model, this); completer->setCaseSensitivity(Qt::CaseInsensitive); completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion); // 关键代码:将补全弹出窗口绑定为当前对话框的子控件 if (QAbstractItemView* popup = completer->popup()) { popup->setParent(this); } test_input->setCompleter(completer);
原理说明
通过popup->setParent(this)将弹出框的父窗口指定为当前QDialog,使其成为对话框的子控件。此时模态对话框的事件循环会将弹出框视为自身的一部分,不再拦截其鼠标事件,点击补全选项即可正常响应。
内容的提问来源于stack exchange,提问作者Chebz
相关产品推荐
相关产品推荐

