2013-02-14 9 views
8

Ho una finestra principale estesa con un QtGui.QTabWidget aggiunto. Sto creando diversi widget estesi da QtGui.QWidget che posso aggiungere e rimuovere nel widget scheda.Come visualizzare una finestra separata da una tabWidget in PySide Qt

Quello che mi piacerebbe fare è avere un pulsante "pop-out" che fa sì che il widget figlio venga rimosso dal widget tab e venga visualizzato come finestra indipendente (e un pulsante "pop-in" da inserire torna nella finestra principale). Lo stesso tipo di idea di Gtalk-in-Gmail. Nota che se chiudo la finestra principale, anche le altre "tab" o "finestre" dovrebbero chiudersi, e dovrei essere in grado di mettere tutte le finestre affiancate e renderle tutte visibili e aggiornate allo stesso tempo. (Visualizzerò dati quasi in tempo reale).

Sono nuovo a Qt, ma se non sbaglio, se un Widget non ha un genitore viene in modo indipendente. Questo funziona, ma poi non ho idea di come avrei potuto "pop", il lunotto posteriore in.

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() 

Il mio intestino dice che ci dovrebbe essere ancora una relazione padre/figlio tra i due.

C'è un modo per mantenere il genitore ma hanno comunque la finestra che si alza autonomamente, o sto fraintendendo lo stile di Qt?

In caso contrario, la creazione di una variabile nel figlio per contenere un collegamento alla finestra principale (come self.parentalUnit = self.parent()) può essere una buona idea o un'idea di hacker/kludgy?

risposta

10

Lasciare la parent come è. Se si rimuove lo parent, la finestra principale di chiusura non chiuderà le schede "mobili", poiché ora sono finestre di livello superiore. windowFlags definisce se un widget è una finestra o un widget figlio. In sostanza, è necessario alternare QtCore.Qt.Window e QtCore.Qt.Widget

seguito è riportato un piccolo ma completo esempio:

#!/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_()) 
+1

Hi @Avaris, cioè _esattamente_ quello che volevo, ho appena non poteva sembrare trovarlo quando ho stava guardando attraverso i documenti. È anche molto più chiaro come il programma scorre qui, quindi grazie per il grande esempio! :) –

+1

@LauraWentworth: Sono contento che aiuti :). – Avaris

0

In Qt, il layout diventa proprietario dei widget aggiunti al layout, quindi gestirlo in modo parentale. È possibile creare un altro widget (senza genitore) che verrà nascosto finché non si preme il pulsante pop-out e quando viene premuto, si rimuove il "widget di estrazione" dal layout originale e lo si aggiunge al layout del widget nascosto. E quando il pulsante pop-in premuto - restituisce il widget al suo layout originale. Per chiudere questa finestra nascosta, quando si chiude la finestra principale, è necessario ridefinire closeEvent(QCloseEvent* ev) a qualcosa di simile (scusate per C++, ma scommetto che, in python è lo stesso):

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 
} 
Problemi correlati