嵌入式设备运行PyQt5时自定义QListWidgetItem内QPushButton无响应
问题原因
该故障是嵌入式裁剪版Qt5的典型兼容问题,桌面Ubuntu使用的是完整X11后端的Qt,事件处理容错逻辑完善,而嵌入式设备常用的裁剪版Qt(多采用eglfs/linuxfb作为平台插件)存在两个明确触发点:
- 创建
QListWidgetItem后未显式设置与自定义控件匹配的sizeHint,嵌入式端Qt不会自动根据setItemWidget的内容计算item的实际交互区域,导致item可点击区域和按钮显示位置错位,点击事件被QListWidget本身拦截,无法传递到内部的QPushButton - 嵌入式端QListWidget默认会抢占视口的所有鼠标/触屏事件用于item选中逻辑,未默认开启向嵌入子控件转发事件的兼容逻辑,该逻辑在桌面端Qt是默认开启的
修复方案
按以下步骤修改代码,无需改动现有UI文件:
- 创建自定义列表项控件时直接指定QListWidget为父对象,避免嵌入式端Qt对象树构造异常
- 每次添加item后显式设置
sizeHint,保证item交互区域和自定义控件显示区域完全重合 - 显式开启QListWidget及其视口的鼠标追踪,关闭事件抢占
- 兜底兼容触屏设备:在QApplication初始化时开启触摸事件转鼠标事件的属性,解决部分触屏设备事件类型不匹配问题
修正后的核心代码
首先在主文件导入部分补充QtCore的引入:
from PyQt5.QtCore import Qt
修改main函数,添加全局属性设置:
def main(): app = QApplication(sys.argv) # 兜底:强制未处理的触摸事件合成鼠标事件,兼容嵌入式触屏 app.setAttribute(Qt.AA_SynthesizeMouseForUnhandledTouchEvents, True) stack = QStackedWidget() collector = CollectorWidget() stack.addWidget(collector) stack.setCurrentWidget(collector) stack.show() sys.exit(app.exec_())
修改create_item_clicked方法:
def create_item_clicked(self): self.listItem = QListWidgetItem() # 创建自定义控件时指定父对象 self.item = CustomListItem(self.qlistwidget_list) self.item.custom_item_button.clicked.connect(self.test_signal) self.qlistwidget_list.addItem(self.listItem) # 显式设置item尺寸与自定义控件匹配 self.listItem.setSizeHint(self.item.sizeHint()) self.qlistwidget_list.setItemWidget(self.listItem, self.item) # 开启鼠标追踪,保证事件能传递到子控件 self.qlistwidget_list.setMouseTracking(True) self.qlistwidget_list.viewport().setMouseTracking(True) self.temp_list_items.append((self.listItem, self.item))
运行效果
修改后部署到嵌入式设备,点击列表项内的按钮即可正常触发控制台打印、标签背景变红的效果,外部原有按钮的功能不受影响。

内容的提问来源于stack exchange,提问作者avp
相关产品推荐
相关产品推荐

