How to pull a separate window from tabWidget in PySide Qt

I have an extended main window with QtGui.QTabWidget added. I create several widgets extended from QtGui.QWidget , which I can add and remove to the tab widget.

What I would like to do is click the pop-up button, which will remove the child widget from the tab widget and come up with its own independent window (and the pop-in button) back to the main window). Same idea as Gtalk-in-Gmail. Please note that if I close the main window, other โ€œtabsโ€ or โ€œwindowsโ€ should also close, and I should be able to place all windows side by side and have them all visible and update at the same time. (I will show the data in real time).

I am new to Qt, but if I'm not mistaken if Widget has no parent, it occurs independently. This works, but then I have no idea how I could "pop" the window back.

 class TCWindow(QtGui.QMainWindow): . . . def popOutWidget(self, child): i = self.tabHolder.indexOf(child) if not i == -1: self.tabCloseRequested(i) self.widgets[i].setParent(None) self.widgets[i].show() 

My gut says that there should still be a relationship between them between parents and children.

Is there a way to save the parent, but still the window opens independently, or do I not understand the Qt style?

Otherwise, creating a variable in the child to bind to the main window (e.g. self.parentalUnit = self.parent() ) would be a good idea or the idea of โ€‹โ€‹hacks / kludgy?

+8
python qt pyside
source share
2 answers

Leave parent as is. If you remove parent , closing the main window does not close the floating tabs, because now they are top-level windows. windowFlags determines whether the widget is a window or child widget. Basically, you need to alternate between QtCore.Qt.Window and QtCore.Qt.Widget

Below is a small but complete example:

 #!/usr/bin/env python # -.- coding: utf-8 -.- import sys from PySide import QtGui, QtCore class Tab(QtGui.QWidget): popOut = QtCore.Signal(QtGui.QWidget) popIn = QtCore.Signal(QtGui.QWidget) def __init__(self, parent=None): super(Tab, self).__init__(parent) popOutButton = QtGui.QPushButton('Pop Out') popOutButton.clicked.connect(lambda: self.popOut.emit(self)) popInButton = QtGui.QPushButton('Pop In') popInButton.clicked.connect(lambda: self.popIn.emit(self)) layout = QtGui.QHBoxLayout(self) layout.addWidget(popOutButton) layout.addWidget(popInButton) class Window(QtGui.QWidget): def __init__(self, parent=None): super(Window, self).__init__() self.button = QtGui.QPushButton('Add Tab') self.button.clicked.connect(self.createTab) self._count = 0 self.tab = QtGui.QTabWidget() layout = QtGui.QVBoxLayout(self) layout.addWidget(self.button) layout.addWidget(self.tab) def createTab(self): tab = Tab() tab.setWindowTitle('%d' % self._count) tab.popIn.connect(self.addTab) tab.popOut.connect(self.removeTab) self.tab.addTab(tab, '%d' % self._count) self._count += 1 def addTab(self, widget): if self.tab.indexOf(widget) == -1: widget.setWindowFlags(QtCore.Qt.Widget) self.tab.addTab(widget, widget.windowTitle()) def removeTab(self, widget): index = self.tab.indexOf(widget) if index != -1: self.tab.removeTab(index) widget.setWindowFlags(QtCore.Qt.Window) widget.show() if __name__ == '__main__': app = QtGui.QApplication(sys.argv) w = Window() w.show() sys.exit(app.exec_()) 
+10
source share

In Qt, a layout takes responsibility for widgets added to a layout, so let it handle parental rights. You can create another widget (without a parent) that will be hidden until you click the pop-up button, and when it is clicked, you will remove the "pop-up widget" from its original layout and add it to the hidden widget layout. And when the power button is pressed, return the widget to its original layout. To close this hidden window, when closing the main window, you need to redefine closeEvent(QCloseEvent* ev) to something like this (sorry for C ++, but I'm sure in python anyway):

 void MainWindow::closeEvent(QCloseEvent* ev) { dw->setVisible(false); // independent of mainwindow widget sw->setVisible(false); // independent of mainwindow widget QWidget::closeEvent(ev); //invoking close event after all the other windows are hidden } 
0
source share

All Articles