Solved Qt for Python Quick Start tutorial refresh bug?
-
Hi and welcome to devnet,
What version of PySide2 are you using ?
On what platform ?
How did you install it ? -
@tomtill said in Qt for Python Quick Start tutorial refresh bug?:
self.text.repaint()
You absolutely should not have to do that! I haven't tried the code in the example, but have looked at it, and it should be fine as it is. I don't know what to say to you other than try it again, and make sure you have the code as shown there....
-
@SGaist, @JonB
I'm using PySide2 5.14.1 on MacOS 10.14.6 (18G3020)
I installed Pyside2 using pip install Pyside2I copied and pasted the code, and ran it using Python 3.8.1, Qt Creator 14.11.0, PyCharm CE (2019.3.3), and from the terminal, with identical results from each. From my limited understanding, I wouldn't expect different behavior since they all refer to the same virtual environment running the same Python installation.
The window comes up with Hello World and the button, but when I click the button nothing happens. If I resize the window, the language of Hello World changes, which should have happened after I pressed the button. Adding the repaint() gives me the expected behavior, but I haven't seen that function used in any tutorial with Qt for Python.
Here is the copy/pasted script:
import sys
import random
from PySide2 import QtCore, QtWidgets, QtGuiclass MyWidget(QtWidgets.QWidget):
def init(self):
super().init()self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"] self.button = QtWidgets.QPushButton("Click me!") self.text = QtWidgets.QLabel("Hello World") self.text.setAlignment(QtCore.Qt.AlignCenter) self.layout = QtWidgets.QVBoxLayout() self.layout.addWidget(self.text) self.layout.addWidget(self.button) self.setLayout(self.layout) self.button.clicked.connect(self.magic) def magic(self): self.text.setText(random.choice(self.hello))
if name == "main":
app = QtWidgets.QApplication([])
widget = MyWidget()
widget.resize(800, 600)
widget.show()
sys.exit(app.exec_()) -
@tomtill
Firstly, please learn to post code here properly protected/formatted. Place a line with 3 adjacent backquotes at the start and at the end. Because you have not done so, you can see your code is missing all its__
(double-underscore) sequences (they show as bold text!), so it won't work for anyone copy/pasting.I have pasted the following code:
import sys import random from PySide2 import QtCore, QtWidgets, QtGui class MyWidget(QtWidgets.QWidget): def __init__(self): super().__init__() self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"] self.button = QtWidgets.QPushButton("Click me!") self.text = QtWidgets.QLabel("Hello World") self.text.setAlignment(QtCore.Qt.AlignCenter) self.layout = QtWidgets.QVBoxLayout() self.layout.addWidget(self.text) self.layout.addWidget(self.button) self.setLayout(self.layout) self.button.clicked.connect(self.magic) def magic(self): self.text.setText(random.choice(self.hello)) if __name__ == "__main__": app = QtWidgets.QApplication([]) widget = MyWidget() widget.resize(800, 600) widget.show() sys.exit(app.exec_())
I confirm that this does work, updating the label text as soon as the button is clicked. I have tested under Ubuntu 19.04 with both PySide2 & PyQt5. Python is 3.7.3, Qt/PySide2/PyQt5 is 5.12.2, as supplied with the Ubuntu release.
I simply do not know why your mileage varies, and you seem to have to force a repaint (one way or another) for it to appear. Maybe @SGaist has some clue....
-
@JonB
Thank you for your instruction, and your efforts to reproduce my finding.
I will triple backquote any code I paste here.I copy and pasted your code into my PyCharm, and observed the same refresh error I saw before.
So it does not appear to be something subtle in my code.From your result, this appears to be MacOS thing, either a Qt bug, a Python bug, or something in my particular setup. I installed the MacOS binaries of both Python and Qt from their respective websites. I cherry picked the Qt installation, since I wished to avoid anything that was not LGPL ( I am a hobbyist, but one can always dream…). Might I have missed an essential component? Should I have built from source?
Is this likely to be a problem in an actual app? A more complicated (useful) app would have a lot more going on which would likely force a refresh anyway, no?
-
@tomtill
It is not your code. You are doing nothing wrong. A more complex example would likely reproduce the issue, and in any case this issue just as exemplified in your code for you must be addressed.You have not likely done anything wrong in whatever you have installed. If you had missed something, you would not get this behaviour. But some subtle incompatibility is always possible.
If you are offering to try to discover more: I would completely uninstall whatever Qt you have. Then, for choice, I would pick a different (older) version to restore, e.g. even back to the 5.12.2 I use. If it happens there too something is very weird. In a miracle world, starting again with uninstall & reinstall may even make it go away, by magic.
-
@tomtill
my guess would be your rather old MacOS version in combination with a new Qt Version is the issue here.Mojave changed the update/repaint signal/event handling, which caused major problems
see here:
https://bugreports.qt.io/browse/QTBUG-68891?focusedCommentId=410788&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanelTL;DR: the DarkMode is to blame.
It should work fine, when you use 5.14.1 like you said you do, but one never knows.
I would suggest updating MacOS or using an LTS version of Qt 5.12.x or 5.9.x
-
@JonB
Of course you are right. Different behavior of the same code on different platforms is surely a bug, not a feature.On that note, do you think that this may be an issue specifically with Pyside2?
I could install PyQt5 in a different virtual environment. If that works, then it would define a bug in Pyside2, no? (I just have to figure out how the code should differ between Pyside2 and PyQt.)
-
@J-Hilk
It looks like this is an open bug report, PYSIDE-695, and has been confirmed by multiple people using Catalina as well as Mojave and various versions of PySide2.https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-695?filter=allopenissues
Apparently it's been around for a while.
-
@Denni-0
Thank you! I enjoyed your rewrite of the code...learning a lot from this sort of thing.Your code works (after adding an underscore after exec) sort of, even though I've tracked down the issue to a previously reported bug in PySide2:
https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-695?filter=allopenissues
Comparing your code to the previous code, I was able to isolate a single line that makes the difference. Adding self.layout.addStretch() to the original code gives the desired refresh (although the message is no longer centered). Commenting out "VBox.addStretch(1)" in your code gives a partial refresh if the window is small, but no refresh once the window is enlarged.
Following a comment made by @alexheinz on the bug report, I can get the desired behavior by adding the line "app.setStyle('Fusion')" in the original code, or "MainEvntHndlr.setStyle('Fusion') " in your code. This also works with "setStyle('Windows')". Apparently the default style (Macintosh) in MacOS is the only one with an issue.
-
I can work around the Pyside2 MacOS refresh bug using app.setStyle('Fusion').
Maybe they'll even fix the bug before I am ready to deploy.
Thank you all for your help figuring this out. I am marking this Topic solved.