2012-01-11 34 views
15

Recientemente he empezado a programar Python (PyQt) en particular. Tengo mi clase principal QMainWindow. Pero quería separarlo de los widgets UI, de modo que todos los elementos de Windows (menús, barras de herramientas, botones comunes) estén en QMainWindow, pero todos los widgets específicos del programa/UI (botones de botones, cuadros combinados, imágenes, casillas de verificación, etc.) están en un QWidget clase. Pero no estoy seguro si estoy haciendo esto bien.PyQt: cómo agregar un widget de IU separado a QMainWindow

  1. tengo un problema con diseños - algo invisible está cubriendo los menús de modo que no son se puede hacer clic con el ratón, creo que no estoy añadiendo mi widget de interfaz de usuario a la ventana principal correctamente

he aquí cómo lo hago:

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. que he visto otros programas Python donde las aplicaciones se dividen en una gran cantidad de pequeños archivos de código (como yo lo entiendo, tener todo en la clase principal se puede leer o inmanejable).

¿Cuál es su sugerencia acerca de descifrar el código en trozos pequeños? ¿Cómo está mejor? ¿O para UI todo puede estar en un gran lugar? ¿Debería dividir el código/clases de IU en un archivo separado?

Gracias.

[SOLUCIONADO]

he encontrado mi error - He eliminado el main_widget de la clase widget de interfaz de usuario (en la actualidad todos los widgets de interfaz de usuario se colocan directamente en el widget de la clase de interfaz de usuario en sí) y sólo hacen esto:

self.main_layout.addWidget(self.form_widget) 

no hay más problemas con los menús

+0

He encontrado mi error. He eliminado el widget_principal del widget UI y me uso como el widget de retención para todos los otros pequeños widgets (botones, líneas de edición, etc.), y la clase principal simplemente crea una instancia del widget UI (ver arriba): el problema del menú resuelto. – linuxoid

Respuesta

20

¿Estás buscando algo como esto? No estoy realmente seguro de lo que su main_widget es

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

Yo recomiendo usar Qt Designer para crear la mayor cantidad de la interfaz de usuario como sea posible.

Le resultará mucho más fácil experimentar con diseños y demás de esa manera, y mantendrá automáticamente la mayoría de las cosas relacionadas con la interfaz de usuario separadas del resto de la lógica de la aplicación. Haga esto para la ventana principal, y también para cualquier cuadro de diálogo, sin embargo simple.

Luego use pyuic4 para compilar los módulos de python de todos los archivos ui, y colóquelos en su propio subpaquete.

Recomendaría usar el indicador -w al compilar los archivos ui. Esto generará una clase de interfaz de usuario de contenedor simple que se puede subclasificar directamente.

Así que su ventana principal terminaría buscando algo como esto:

from ui.mainwindow import MainWindowUI 

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

Tenga en cuenta que todos los widgets añadidos en Qt Designer son ahora accesibles directamente como atributos de la instancia MainWindow.

No me preocuparía dividir su aplicación en módulos más pequeños hasta más adelante en el desarrollo.Puede que no sea necesario, pero si lo hace, será más obvio cómo hacerlo una vez que la aplicación se vuelva más compleja.

No existen reglas estrictas: cada proyecto es diferente.

+1

Solía ​​usar Qt Designer, pero no me gusta su código generado, se ve horrible y es difícil de cambiar más adelante, también agrega mucha basura que realmente no necesito. Es por eso que comencé a escribir IU desde cero. De esta manera controlo cada línea de código. Aunque me puede estar perdiendo algo, aprenderé. Gracias por su respuesta. – linuxoid

+5

@ user665327. Has entendido mal el propósito de los módulos generados. No son _menos_ para editar. Solo están destinados para _importar_. No voy a decir que haya nada de malo escribiendo el código de UI a mano, pero te estás perdiendo muchísimo al no usar Qt Designer. Por lo menos, debes usarlo como una herramienta para la experimentación. E incluso si no usas el código generado por 'pyuic', aún puedes aprender _una_ cantidad viendo cómo funciona (esto es especialmente cierto cuando se trata de la administración del diseño). – 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()) 

manera correcta !!!

Cuestiones relacionadas