Widgets are not updated - is this a bug?

Phil Thompson phil at riverbankcomputing.com
Tue Sep 15 14:29:04 BST 2020


On 15/09/2020 04:01, Jeremy Katz wrote:
> On 24/Jun/20 23:46, Christian ARNAUD wrote:
>> Hi,
>> 
>>  
>> 
>> I ran in a strange behavior where widgets in the view aren’t properly
>> refreshed on change.
>> 
>> Here is the code, developed to show the problem:
>> 
> [ code omitted ]  
>> 
>> If the pushbutton is clicked with the mouse or with the space key 
>> (after
>> getting the focus with Tab), the text in the lineedit is not 
>> refreshed.
>> If a repaint is forced, it is.
>> 
>> If the pushbutton is clicked with the enter key (after getting the 
>> focus
>> with Tab), the text in the lineedit is correctly refreshed.
>> 
>>  
>> 
>> Any idea?
>> 
>>  
>> 
>> My env:
>> 
>> OSX Catalina 10.15.5
>> Python 3.6
>> PyQt: 15.0
>> 
> 
> I'm having similar issues with macOS 10.15.6, Python 3.6.3, Qt 5.15.0,
> and PyQt 5.15.0. This doesn't appear to be an issue on Windows 10 or
> Linux/X11, and doesn't occur on the same version of macOS with a nearly
> identical C++ program.
> 
> The QTextEdit is correctly painted as soon as focus is transferred to
> another window via mouse click, command-tab, etc. Scheduling the
> operation that eventually leads to a repaint for the next iteration of
> the event loop also works.
> 
> import sys
> import PyQt5.QtWidgets as W
> import PyQt5.QtCore as C
> 
> app = W.QApplication(sys.argv)
> w = W.QWidget()
> layout = W.QVBoxLayout()
> edit = W.QTextEdit()
> edit.setText(C.qVersion())
> 
> button = W.QPushButton("broken")
> button.clicked.connect(edit.clear)
> 
> button2 = W.QPushButton("not broken")
> button2.clicked.connect(lambda: C.QMetaObject.invokeMethod(edit,
> "clear", C.Qt.QueuedConnection))
> 
> layout.addWidget(button)
> layout.addWidget(button2)
> layout.addWidget(edit)
> w.setLayout(layout)
> w.show()
> app.exec_()

I can reproduce the problem and I can confirm that an equivalent C++ 
version does not exhibit the problem.

A simpler way to get a working version is to change the connection type 
in the connect() call...

button.clicked.connect(edit.clear, C.Qt.QueuedConnection)

However I am currently at a loss about what is happening. I am using a 
version of PyQt that only uses "plain" Qt classes which does not allow 
Python re-implementations of C++ virtuals. This means that while the Qt 
event loop is running (ie. in the call to exec()), *no* PyQt is executed 
- yet the problem still exists. It's almost as if the very presence of 
Python is having an effect.

Any insight would be welcome...

Phil


More information about the PyQt mailing list