可滚动小部件的 QPaintEvent 事件矩形
QPaintEvent event rect for scrollable widget
我有一个 QPaintEvent 重写用于具有固定大小集的自定义小部件。这个固定大小可以根据实例改变,但在这个简单的例子中,我设置了它。但是 PaintEvent 没有考虑到它,所以当用户向右滚动时,矩形不应该绘制圆角,因为小部件超出了可见视口。我该如何解决这个问题?
正确绘制的完整小部件...
当我调整对话框的大小并向右滚动时,您会看到圆角出现在左侧......但它不应该出现。
它们应该是这样的...
代码
import os
import sys
from PySide2 import QtGui, QtWidgets, QtCore, QtSvg
class Card(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Card, self).__init__(parent=parent)
self.label = QtWidgets.QLabel('Help This Paint Event Is Broken')
self.label.setFixedHeight(40)
self.label.setFixedWidth(300)
self.mainLayout = QtWidgets.QVBoxLayout(self)
self.mainLayout.addWidget(self.label)
# overrides
def paintEvent(self, event):
painter = QtGui.QPainter()
painter.begin(self)
painter.setOpacity(1.0)
painter.setRenderHints(QtGui.QPainter.Antialiasing)
painter.setPen(QtGui.QColor(0, 0, 0, 128))
painter.setPen(QtCore.Qt.NoPen)
painter.setBrush(QtGui.QColor('#F44336'))
painter.drawRoundedRect(event.rect(), 12, 12)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.end()
class ListViewExample(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ListViewExample, self).__init__(parent)
self.resize(200,200)
self.listView = QtWidgets.QListWidget()
self.listView.setSpacing(10)
self.listView.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.listView.verticalScrollBar().setSingleStep(10)
# layout
self.mainLayout = QtWidgets.QVBoxLayout()
self.mainLayout.setContentsMargins(0,0,0,0)
self.mainLayout.addWidget(self.listView)
self.setLayout(self.mainLayout)
for x in range(50):
wgt = Card()
self.appendItem(wgt)
def appendItem(self, widget):
lwi = QtWidgets.QListWidgetItem()
lwi.setSizeHint(widget.sizeHint())
self.listView.addItem(lwi)
self.listView.setItemWidget(lwi, widget)
################################################################################
# Widgets
################################################################################
def unitTest_CardDelegate():
app = QtWidgets.QApplication(sys.argv)
window = ListViewExample()
window.show()
app.exec_()
if __name__ == '__main__':
pass
unitTest_CardDelegate()
QPaintEvent::rect()
returns 可见矩形,而不是小部件本身的矩形,因此您观察到此行为。解决方案是:
painter.drawRoundedRect(self.rect(), 12, 12)
我有一个 QPaintEvent 重写用于具有固定大小集的自定义小部件。这个固定大小可以根据实例改变,但在这个简单的例子中,我设置了它。但是 PaintEvent 没有考虑到它,所以当用户向右滚动时,矩形不应该绘制圆角,因为小部件超出了可见视口。我该如何解决这个问题?
正确绘制的完整小部件...
当我调整对话框的大小并向右滚动时,您会看到圆角出现在左侧......但它不应该出现。
它们应该是这样的...
代码
import os
import sys
from PySide2 import QtGui, QtWidgets, QtCore, QtSvg
class Card(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Card, self).__init__(parent=parent)
self.label = QtWidgets.QLabel('Help This Paint Event Is Broken')
self.label.setFixedHeight(40)
self.label.setFixedWidth(300)
self.mainLayout = QtWidgets.QVBoxLayout(self)
self.mainLayout.addWidget(self.label)
# overrides
def paintEvent(self, event):
painter = QtGui.QPainter()
painter.begin(self)
painter.setOpacity(1.0)
painter.setRenderHints(QtGui.QPainter.Antialiasing)
painter.setPen(QtGui.QColor(0, 0, 0, 128))
painter.setPen(QtCore.Qt.NoPen)
painter.setBrush(QtGui.QColor('#F44336'))
painter.drawRoundedRect(event.rect(), 12, 12)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.end()
class ListViewExample(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ListViewExample, self).__init__(parent)
self.resize(200,200)
self.listView = QtWidgets.QListWidget()
self.listView.setSpacing(10)
self.listView.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.listView.verticalScrollBar().setSingleStep(10)
# layout
self.mainLayout = QtWidgets.QVBoxLayout()
self.mainLayout.setContentsMargins(0,0,0,0)
self.mainLayout.addWidget(self.listView)
self.setLayout(self.mainLayout)
for x in range(50):
wgt = Card()
self.appendItem(wgt)
def appendItem(self, widget):
lwi = QtWidgets.QListWidgetItem()
lwi.setSizeHint(widget.sizeHint())
self.listView.addItem(lwi)
self.listView.setItemWidget(lwi, widget)
################################################################################
# Widgets
################################################################################
def unitTest_CardDelegate():
app = QtWidgets.QApplication(sys.argv)
window = ListViewExample()
window.show()
app.exec_()
if __name__ == '__main__':
pass
unitTest_CardDelegate()
QPaintEvent::rect()
returns 可见矩形,而不是小部件本身的矩形,因此您观察到此行为。解决方案是:
painter.drawRoundedRect(self.rect(), 12, 12)