0

I don't understand what mechanic/trigger causes the layout to update. In the simple example I created, the button's text is updated real-time inside the method, but the layout does not update until after the method is completed even though "I should see 2 button(s)" is correctly reported. How do I get the layout/window to add the button to the layout real-time?

import sys
import time
from PySide import QtCore, QtGui


class Form(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.button = QtGui.QPushButton("Add")
        self.newButton= QtGui.QPushButton("")
        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)
        self.connect(self.button, QtCore.SIGNAL("clicked()"),self.addButton)
        print()

    def addButton(self):
        self.button.setText("Clicked")
        if self.layout.count() > 1:
            self.layout.itemAt(1).widget().deleteLater()
        self.repaint()
        self.layout.update()
        print("I should see " + str(self.layout.count()) + " button(s)")
        time.sleep(3)
        self.layout.addWidget(self.newButton)
        self.repaint()
        self.layout.update()
        print("I should see " + str(self.layout.count()) + " button(s)")
        time.sleep(3)
        self.button.setText("")
        self.button.setEnabled(False)
        self.newButton.setText("New")


app = QtGui.QApplication(sys.argv)
a=Form()
a.show()
app.exec_()

Please explain or demonstrate how to make the new button appear inside the method.

  • 1
    You need to call `repaint()` after `layout.update()`, not before it. – Pavel Strakhov Apr 27 '14 at 10:50
  • @PavelStrakhov No, this code is fundamentally broken, and `repaint` should never be called without having a very good reason. The text `repaint(` appears only 95 times in the entire qtbase module, vs. `update(`'s 1132 times! That should count for something. – Kuba hasn't forgotten Monica Apr 28 '14 at 15:07

1 Answers1

0

You never run the event loop within addButton. There's no need at all to call repaint or update. As soon as the control returns to the event loop, you'll see the new buttons on the screen.

As a proof-of-concept, your code could be modified to call QCoreApplication.processEvents() instead of repaint(). It's still bad code, though. You should not call sleep - while you do so, literally nothing happens in your code, so it is entirely pointless.

Basically, simply add the buttons and exit the method. It will work. You're overcomplicating things for no reason at all.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313