Widgets are not updated - is this a bug?

Jeremy Katz jkatz at volexity.com
Tue Sep 15 21:14:04 BST 2020



On 15/Sep/20 06:29, Phil Thompson wrote:
> 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)

Indeed, as does emitting a signal connected to the slot from another
thread connected with an AutoConnection.

> 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...

Possibly related, and not easily fixed by the queued connection APIs:
I'm having similar painting failures with the background of a QMdiArea
when a QMdiSubWindow is moved. It's not completely reliable, but the
trailing edge or corner of a moved or resized subwindow isn't always
overwritten with the background color.

I haven't experimented with reposting resize events yet.


More information about the PyQt mailing list