【发布时间】:2021-01-29 15:47:18
【问题描述】:
我正在使用 listView 和自定义委托。通过paint 函数,我绘制了一组控制元素,这样列表的每一行就好像它是一个小部件,而不是一个小部件。这对于性能至关重要,因为该列表由数十万个元素组成,如 here 和 here 所指出的。
唯一的问题是 QStyleOptionSlider 复杂控件:如果我要求 CC.ScrollBar 控件呈现在视图的左上角而不是我想要的位置。如果在QApplication.style().drawComplexControl(QStyle.CC_ScrollBar, self.scrollOptions, painter) 中我要求CC_Slider(而不是CC_ScrollBar),则控件将呈现在预期的位置。
我还尝试从真正的滚动小部件初始化样式,但没有任何改变。
我想知道是我做错了什么还是库有问题,因为我绘制的所有其他控件都可以正常工作。我注意到的唯一区别是其他元素(例如框架、标签、按钮)有自己的 QStyleOption 类,而滚动条与滑块类合并,但引用docs:
QStyleOptionSlider 包含了 QStyle 函数绘制 QSlider 和 QScrollBar 所需的所有信息。
调试信息:Python 3.8.6 / PyQt 5.15.1 / Pyqt-tools 5.15.1.2 / Windows 10
小例子
from PyQt5.QtCore import QSize, Qt, QRect
from PyQt5.QtGui import QColor
from PyQt5.QtGui import QStandardItem
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QStyle
from PyQt5.QtWidgets import QStyledItemDelegate, QApplication, QStyleOptionFrame, \
QStyleOptionSlider
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.inferenceListView = QtWidgets.QListView(self.centralwidget)
self.inferenceListView.setGridSize(QtCore.QSize(0, 200))
self.inferenceListView.setObjectName("inferenceListView")
self.gridLayout.addWidget(self.inferenceListView, 0, 1, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.setupProposals()
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
def setupProposals(self):
self.delegate = MyDelegate()
# self.delegate.initScroll(self.horizontalScrollBar)
model = QStandardItemModel(0, 0)
for index in range(0, 5000):
model.appendRow(QStandardItem(str(index)))
self.inferenceListView.setItemDelegateForRow(index, self.delegate)
self.inferenceListView.setModel(model)
class MyDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent)
self.frame = QStyleOptionFrame()
# ---------------
self.scrollOptions = QStyleOptionSlider()
self.scrollOptions.orientation = Qt.Vertical
self.scrollOptions.LayoutDirectionAuto = Qt.LayoutDirectionAuto
self.scrollOptions.orientation = Qt.Vertical
self.scrollOptions.state = QStyle.State_Enabled
self.scrollOptions.maximum = 10
self.scrollOptions.minimum = 0
self.scrollOptions.sliderValue = 0
def initScroll(self, scroll):
self.scrollOptions.initFrom(scroll)
def sizeHint(self, option, index):
return QSize(150, 200)
def paint(self, painter, option, index):
optX = option.rect.x()
optY = option.rect.y()
optH = option.rect.height()
optW = option.rect.width()
painter.fillRect(option.rect, QColor(100, 100, 100, 100))
painter.drawLine(optX, optY + optH, optX + optW, optY + optH)
QApplication.style().drawControl(QStyle.CE_ShapedFrame, self.frame, painter)
self.scrollOptions.rect = QRect(optX + 100, optY + 100, 50, 80)
# OK WITH CC_SLIDER
#QApplication.style().drawComplexControl(QStyle.CC_Slider, self.scrollOptions, painter)
# WRONG PLACE WITH CC_SCROLLBAR
QApplication.style().drawComplexControl(QStyle.CC_ScrollBar, self.scrollOptions, painter)
def editorEvent(self, event, model, option, index):
return False
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
编辑
目前似乎是与 Windows 相关的问题。我有一个使用 Mac 的同事运行上面的代码,滚动条被绘制在正确的位置。我附上了在两种情况下在 Windows 上发生的情况的图像:
【问题讨论】:
标签: python-3.x windows qt pyqt5