2012-01-11 19 views
15

Ho solo recentemente iniziato a programmare e Python (PyQt) in particolare. Ho la mia classe principale QMainWindow. Ma volevo separarlo dai widget dell'interfaccia utente, in modo che tutte le finestre (menu, barre degli strumenti, pulsanti comuni) siano in QMainWindow, ma tutti i widget specifici dell'interfaccia utente/programma (pulsanti, caselle combinate, immagini, caselle di controllo ecc.) Si trovano in un numero QWidget separato classe. Ma non sono sicuro se lo sto facendo bene.PyQt - come aggiungere widget UI separati a QMainWindow

  1. Ho un problema con layout - qualcosa di invisibile sta coprendo i menu in modo che essi non sono cliccabili con il mouse, penso che non sto aggiungendo il mio widget di interfaccia utente per la finestra principale correttamente

Ecco come lo faccio:

class MyMainWindow(QMainWindow): 
    def __init__(self, parent = None): 
     super(MyMainWindow, self).__init__(parent) 

     self.main_widget = QWidget(self) 
     ... 
     self.form_widget = FormWidget(self) 
     #This is my UI widget 

     self.main_layout = QVBoxLayout(self.main_widget) 
     self.main_layout.sizeConstraint = QLayout.SetDefaultConstraint 
     self.main_layout.addWidget(self.form_widget.main_widget) 
     #form_widget has its own main_widget where I put all other widgets onto 

     self.main_widget.setLayout(self.main_layout) 
     self.setCentralWidget(self.main_widget) 
  1. ho visto altri programmi Python in cui le applicazioni sono suddivise in un sacco di piccoli file di codice (se ho capito bene, avere tutto in sulla classe principale è illeggibile o ingestibile).

Qual è il tuo suggerimento su come suddividere il codice in piccoli pezzi? Come va meglio? O per l'interfaccia utente può essere tutto in un unico grande posto? Dovrei interrompere il codice/le classi dell'interfaccia utente in un file separato?

Grazie.

[risolto]

ho trovato il mio errore - ho cancellato il main_widget dalla classe widget di interfaccia utente (ora tutti i widget UI sono posti direttamente sul widget Class UI stessa) e solo fanno questo:

self.main_layout.addWidget(self.form_widget) 

nessun problema con i menu

+0

Ho trovato il mio errore. Ho cancellato main_widget dal widget UI e uso se stesso come widget di mantenimento per tutti gli altri piccoli widget (pulsanti, editline ecc.) E la classe principale crea semplicemente un'istanza del widget UI (vedi sopra) - il problema del menu risolto. – linuxoid

risposta

20

Stai cercando qualcosa di simile? Io non sono davvero sicuro di quello che il vostro main_widget è

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

import sys 

class MyMainWindow(QMainWindow): 

    def __init__(self, parent=None): 

     super(MyMainWindow, self).__init__(parent) 
     self.form_widget = FormWidget(self) 
     self.setCentralWidget(self.form_widget) 


class FormWidget(QWidget): 

    def __init__(self, parent):   
     super(FormWidget, self).__init__(parent) 
     self.layout = QVBoxLayout(self) 

     self.button1 = QPushButton("Button 1") 
     self.layout.addWidget(self.button1) 

     self.button2 = QPushButton("Button 2") 
     self.layout.addWidget(self.button2) 

     self.setLayout(self.layout) 

app = QApplication([]) 
foo = MyMainWindow() 
foo.show() 
sys.exit(app.exec_()) 
7

mi consiglia di utilizzare Qt Designer per creare la maggior quantità di UI come possibile.

Troverai molto più facile sperimentare i layout e così via, e manterrà automaticamente la maggior parte delle cose relative all'interfaccia utente separate dal resto della logica dell'applicazione. Fai questo per la finestra principale e anche per qualsiasi finestra di dialogo, per quanto semplice.

Quindi utilizzare pyuic4 per compilare i moduli python da tutti i file ui e metterli tutti insieme nel proprio sottopropacchetto.

Si consiglia di utilizzare il flag -w durante la compilazione di file ui. Questo genererà una semplice classe UI wrapper che può essere sottoclassata direttamente.

Così la vostra finestra principale finirebbe cercando qualcosa di simile:

from ui.mainwindow import MainWindowUI 

class MainWindow(MainWindowUI): 
    def __init__(self): 
     super(MainWindow, self).__init__() 
     # connect signals... 
     # do other setup stuff... 

Si noti che tutti i widget aggiunti in Qt Designer sono ora accessibili direttamente come attributi dell'istanza MainWindow.

Non mi preoccuperei di suddividere l'applicazione in moduli più piccoli fino a più tardi in fase di sviluppo.Potrebbe non rivelarsi necessario, ma se lo fa, diventerà più ovvio come farlo una volta che l'applicazione inizia a diventare più complessa.

Non ci sono regole dure e veloci - ogni progetto è diverso.

+1

Ho usato Qt Designer, ma non mi piace il suo codice generato, sembra orribile ed è difficile cambiarlo in seguito, aggiunge anche un sacco di spazzatura che non ho davvero bisogno. Ecco perché ho iniziato a scrivere UI da solo. In questo modo controllo ogni riga di codice. Sebbene possa mancare qualcosa, ma imparerò. Grazie per la risposta. – linuxoid

+5

@ user665327. Hai completamente frainteso lo scopo dei moduli generati. Non sono _meant_ per la modifica. Sono pensati solo per _importare_. Non dirò che c'è qualcosa di sbagliato nel scrivere codice UI a mano, ma ti stai perdendo moltissimo non usando Qt Designer. Per lo meno, dovresti usarlo come strumento per l'esperimento. E anche se non usi il codice generato da 'pyuic', puoi ancora imparare _a molto_ vedendo come funziona (questo è particolarmente vero quando si tratta di gestione del layout). – ekhumoro

8
import sys 
from PyQt4 import QtCore, QtGui 


class MainWindow(QtGui.QMainWindow): 

    def __init__(self, parent=None): 
     super(MainWindow, self).__init__(parent) 
     self.form_widget = FormWidget(self) 
     _widget = QtGui.QWidget() 
     _layout = QtGui.QVBoxLayout(_widget) 
     _layout.addWidget(self.form_widget) 
     self.setCentralWidget(_widget) 

class FormWidget(QtGui.QWidget): 

    def __init__(self, parent): 
     super(FormWidget, self).__init__(parent) 
     self.__controls() 
     self.__layout() 

    def __controls(self): 
     self.label = QtGui.QLabel("Name for backdrop") 
     self.txted = QtGui.QLineEdit() 
     self.lbled = QtGui.QLabel("Select a readNode") 
     self.cmbox = QtGui.QComboBox() 

    def __layout(self): 
     self.vbox = QtGui.QVBoxLayout() 
     self.hbox = QtGui.QHBoxLayout() 
     self.h2Box = QtGui.QHBoxLayout() 

     self.hbox.addWidget(self.label) 
     self.hbox.addWidget(self.txted) 

     self.h2Box.addWidget(self.lbled) 
     self.h2Box.addWidget(self.cmbox) 

     self.vbox.addLayout(self.hbox) 
     self.vbox.addLayout(self.h2Box) 
     self.setLayout(self.vbox) 

def main(): 
    app = QtGui.QApplication(sys.argv) 
    win = MainWindow() 
    win.show() 
    app.exec_() 

if __name__ == '__main__': 
    sys.exit(main()) 

modo corretto !!!

Problemi correlati