I have a QMainWindow which has the status bar enabled. I then have nested widgets/layouts that make up child page of the QMainWindow. Here is a sample hierarchy of how the widgets are arranged:
In MainTabs, I perform some logic and want to show a message on the status bar that is controlled by Main. I found a couple of options searching for solutions. One is doing the chained parent() option, so self.parent().parent()... which eventually gets access to the Main status bar. Another option is using signals/slots, which is what I am doing.
My current flow is as follows:
I have it working with the multiple signals, but is there a better way to do this? Can the Main QMainWindow be accessed directly from a nested widget?
You can access the top level window using window()
, but that would be just an assumption: a child object should never assume things about its parents, at any level, nor try to directly access its elements.
While using signals (possibly, chained, for complex situations) might be fine, there's no need for this, as long as the QMainWindow uses a proper status bar (either created by calling statusBar()
or manually set with setStatusBar()
).
What you could actually do is to explicitly call setStatusTip()
in the widget, and then enforce the status tip visibility, by creating a QStatusTipEvent, then use QCoreApplication.sendEvent()
.
The following example shows a basic widget that is able to emit such event and eventually hides it after a timeout, unless the mouse leaves the widget before that:
class Test(QWidget):
def __init__(self):
super().__init__()
layout = QHBoxLayout(self)
self.spinBox = QSpinBox()
self.button = QPushButton('Update status tip')
layout.addWidget(self.spinBox)
layout.addWidget(self.button)
self.button.clicked.connect(self.showStatusTip)
self.statusTimer = QTimer(singleShot=True,
interval=2000, timeout=self.hideStatusTip)
def leaveEvent(self, event):
self.hideStatusTip()
self.statusTimer.stop()
def showStatusTip(self):
tip = 'Value is {}'.format(self.spinBox.value())
QApplication.sendEvent(self, QStatusTipEvent(tip))
self.statusTimer.start()
def hideStatusTip(self):
QApplication.sendEvent(self, QStatusTipEvent(''))