[英]Overriding paintEvent in PyQt5 and PySide2
我一直在使用PyQt和PySide。 今天我偶然发现了一个奇怪的行为:重新实现paintEvent似乎不适用于Qt5的Python版本。 我在Qt4中从未遇到过这个问题。
from PySide2 import QtWidgets, QtCore, QtGui # use pyside
# from PyQt5 import QtWidgets, QtCore, QtGui # use pyqt
import sys
class TagWidget(QtWidgets.QWidget):
def __init__(self, parent):
super().__init__(parent)
print("__init__")
def paintEvent(self, e):
# this is called or not
# depends (see below)
print("paintEvent")
raise(AssertionError)
class MyGui(QtWidgets.QMainWindow):
def __init__(self,parent=None):
super(MyGui, self).__init__()
self.setupUi()
def setupUi(self):
self.setGeometry(QtCore.QRect(100,100,500,500))
self.w=QtWidgets.QWidget(self)
self.setCentralWidget(self.w)
self.lay = QtWidgets.QHBoxLayout(self.w)
self.image = TagWidget(self.w)
self.lay.addWidget(self.image)
# return
# exit here, and TagWidget.paintEvent
# is still being called
self.file_list = QtWidgets.QListWidget(self.w)
# return
# exit here, and TagWidget.paintEvent
# is still being called
self.lay.addWidget(self.file_list)
# .. but if we reach all the way here,
# TagWidget.paintEvent is never called !
def main():
app=QtWidgets.QApplication(["test_app"])
mg=MyGui()
mg.show()
app.exec_()
if (__name__=="__main__"):
main()
所以,我们只是测试是否正在调用paintEvent(通过在调用时引发AssertionError)。
一旦我们将另一个小部件添加到TagWidget所在的相同布局,paintEvent就不再有效了。
太奇怪了。 帮助赞赏。
当需要重新绘制时调用paintEvent()
,如果窗口小部件的size(0, 0)
或大小无效或者隐藏了该方法未被调用,那么在你的情况下会发生这种情况,当使用布局时它会默认情况下,取sizeHint()
的大小,默认情况下,QWidget sizeHint()
是QSize(-1, -1)
,因此无需绘制。
所以解决方案是设置一个合适的sizeHint()
:
class TagWidget(QtWidgets.QWidget):
def paintEvent(self, e):
print("paintEvent")
raise(AssertionError)
def sizeHint(self):
print("default sizeHint: ", super(TagWidget, self).sizeHint())
return QtCore.QSize(640, 480)
我用PyQt4
和PySide
尝试过,同样的问题发生了,所以问题不是Qt而是特别的例子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.