如何去除PyQt5中QComboBox控件的自动滚动问题?
PyQt5 QComboBox下拉列表异常滚动问题解决
问题描述
为QComboBox的QAbstractItemView设置padding和border样式后,鼠标悬停在下拉箭头区域时,下拉列表会自动滚动;移除这两个样式后滚动现象消失,但需要保留样式效果。
问题代码
from PyQt5 import QtWidgets from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt from PyQt5.QtGui import QBrush, QColor import sys class Ui_MainWindow(QMainWindow): def __init__(self): super().__init__() self.comboBox = QComboBox(self) self.comboBox.setStyleSheet(''' QComboBox QAbstractItemView { padding: 5px; border: 2px solid rgb(0, 0, 0); }''') self.comboBox.addItem("1") self.comboBox.addItem("2") self.comboBox.addItem("3") self.comboBox.addItem("1") self.comboBox.addItem("2") self.comboBox.addItem("3") self.comboBox.addItem("1") self.comboBox.addItem("2") self.comboBox.addItem("3") self.comboBox.addItem("1") self.comboBox.addItem("2") self.comboBox.addItem("3") self.comboBox.addItem("1") self.comboBox.addItem("2") self.comboBox.addItem("3") self.comboBox.addItem("1") self.comboBox.addItem("2") self.comboBox.addItem("3") self.comboBox.addItem("1") self.comboBox.addItem("2") self.comboBox.addItem("3") if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) MainWindow = Ui_MainWindow() MainWindow.show() sys.exit(app.exec_())
解决方法
方案一:调整样式作用对象(推荐)
直接给QAbstractItemView设置padding会导致视图滚动区域计算错误,将内边距样式转移到列表项上即可解决问题,同时保留所需样式效果:
QComboBox QAbstractItemView { border: 2px solid rgb(0, 0, 0); } QComboBox QAbstractItemView::item { padding: 5px; }
修改后的完整代码:
from PyQt5 import QtWidgets from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt import sys class Ui_MainWindow(QMainWindow): def __init__(self): super().__init__() self.comboBox = QComboBox(self) self.comboBox.setStyleSheet(''' QComboBox QAbstractItemView { border: 2px solid rgb(0, 0, 0); } QComboBox QAbstractItemView::item { padding: 5px; }''') for _ in range(7): self.comboBox.addItems(["1", "2", "3"]) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) MainWindow = Ui_MainWindow() MainWindow.show() sys.exit(app.exec_())
方案二:自定义视图过滤错误滚动事件
如果必须在QAbstractItemView上设置padding,可以自定义QListView,过滤掉鼠标悬停在箭头区域时的滚动触发事件:
from PyQt5 import QtWidgets from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt, QEvent import sys class CustomListView(QListView): def viewportEvent(self, event): # 过滤鼠标悬停在箭头区域时的滚动相关事件 if event.type() in (QEvent.Wheel, QEvent.MouseMove): combo_box = self.parentWidget() if not combo_box: return super().viewportEvent(event) # 计算下拉箭头区域的矩形范围 arrow_rect = combo_box.rect() arrow_rect.setLeft(arrow_rect.width() - 20) # 判断鼠标是否处于箭头区域内 if combo_box.mapFromGlobal(self.cursor().pos()) in arrow_rect: return True return super().viewportEvent(event) class Ui_MainWindow(QMainWindow): def __init__(self): super().__init__() self.comboBox = QComboBox(self) # 为ComboBox设置自定义视图 self.list_view = CustomListView() self.comboBox.setView(self.list_view) self.comboBox.setStyleSheet(''' QComboBox QAbstractItemView { padding: 5px; border: 2px solid rgb(0, 0, 0); }''') for _ in range(7): self.comboBox.addItems(["1", "2", "3"]) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) MainWindow = Ui_MainWindow() MainWindow.show() sys.exit(app.exec_())
内容的提问来源于stack exchange,提问作者Mikhail
相关产品推荐
相关产品推荐

