2011-12-17 22 views
5

Durante intervalos regulares de mi programa, un widgets de bloque (de 3 apilados) deben agregarse a un diseño horizontal. Dado que los widgets dentro de cada bloque son importantes entre sí, deseo encapsular cada pila como su propio widget (lo que hace que el diseño sea mucho más fácil).PyQt4 - Estructura de clase de widget personalizado?

Tengo problemas para que PyQt4 reconozca mi 'pila' como un widget.

I hizo que la pila Widget en Qt Designer (como formulario: Widget) y se convierte a una .py través
'pyuic4 DesignerFile.ui> ClassFile.py'.

Ahora parece que no puedo agregar esta 'pila' (widget padre de 3 widgets secundarios) al diseño mediante .addWidget (Clase).

Probé la construcción de una superclase de la clase de pila (porque tengo que añadir más funcionalidad a la pila), pero la instancia de la clase está bien ...

  • no se reconoce como un widget
  • Invisible
  • defectuoso porque no tengo idea de cómo estructurar la superclase.

Aquí es lo que estoy fallando con en el momento (aunque se trata de la estructura de clases octavo He tratado):

from ClassFile import ClassCode 

class Stack(ClassCode): 
    def __init__(self,parent= None): 
     QtGui.QWidget.__init__(self,parent) 

Podría alguien me ayude a estructurar este o me llevan a algunos buenos ejemplos ?
(he imitado el código en ambas de las siguientes fuentes, pero sin resultado !!
http://lateral.netmanagers.com.ar/stories/27.html#what-you-need-to-follow-the-tutorial
http://zetcode.com/tutorials/pyqt4/customwidgets/)

Gracias!

Especificaciones:
pitón 2.7.2
PyQt4
Windows 7

Respuesta

5

Al compilar un módulo de Python desde un archivo ui con las opciones por defecto, será (entre otras cosas) generar una clase simple "configuración". En resumen, la clase de configuración se verá así:

class Ui_ClassCode(object): 
    def setupUi(self, ClassCode): 
     ClassCode.setObjectName("ClassCode") 
     # bunch of boiler-plate ui code goes here 
     self.retranslateUi(ClassCode) 
     QtCore.QMetaObject.connectSlotsByName(ClassCode) 

    def retranslateUi(self, ClassCode): 
     pass 

Hay un par de cuestiones que deben tenerse en cuenta aquí que son relevantes para la pregunta.

En primer lugar, la clase de configuración está diseñada para ser utilizada como mixin en lugar de como una subclase directa.Su tarea es "inyectar" ui en un widget de host que se pasa al método setupUI.

En segundo lugar, a la clase de configuración se le da un identificador feo y no epónimo que se crea anteponiendo "Ui_" a la propiedad objectName que se configuró en Designer.

Afortunadamente, pyuic4 proporciona una forma de eludir estos dos problemas. Todo lo que se necesita es usar la opción -w al compilar el módulo de Python desde el archivo de interfaz de usuario:

pyuic4 -w designerfile.ui > classfile.py 

Esto agregará una clase contenedora que (1) puede ser una subclase fácilmente, y (2) tiene el nombre de clase que malditamente le diste en Qt Designer.

La clase contenedora se verá algo como esto:

class ClassCode(QtGui.QWidget, Ui_ClassCode): 
    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()): 
     QtGui.QWidget.__init__(self, parent, f) 

     self.setupUi(self) 

Como se puede ver, que no hace nada especial: fácilmente se podría replicar lo que hace en su propio código. Pero, IMO, hace que los módulos compilados sean mucho más intuitivos de usar.

Por ejemplo:

from PyQt4 import QtGui, QtCore 
from classfile import ClassCode 

class Stack(ClassCode): 
    def __init__(self, parent=None): 
     ClassCode.__init__(self, parent) 

class Window(QtGui.QMainWindow): 
    def __init__(self): 
     QtGui.QMainWindow.__init__(self) 
     self.stack = Stack(self) 
     self.setCentralWidget(self.stack) 
+0

¿Es posible pasar una cadena al constructor (cuando se crea la instancia del widget) para usarla a través del widget? Ejemplo: x = Stack ('cat') –

+1

@AntiEarth. Seguro: puedes diseñar tu subclase 'Stack' de la manera que quieras, como subclasificar cualquier otro widget Qt. Por lo tanto, la firma de 'Stack .__ init__' podría cambiarse a, p. '__init __ (self, name, parent = None)'. – ekhumoro

1

En primer lugar, es más apropiado llamar a los padres __init__ con el uso de super. Eso asegurará que se invoque el método en la superclase adecuada. En segundo lugar, al usar una clase construida con pyuic, debe llamar al self.setupUi(self) desde su método __init__. Y, por último, debe asegurarse de heredar múltiples de la clase Qt adecuada y de la clase generada pyuic (que en realidad es más una mezcla).

Por lo tanto, algo como esto:

from ClassFile import ClassCode 

class Stack(QtGui.QWidget, ClassCode): 
    def __init__(self,parent= None): 
     super(Stack, self).__init__(parent) 
     self.setupUi(self) 
+1

En realidad debería hereda de la primera QWidget deseada, y en segundo lugar de la ClassCode que fue generado por pyuic – jdi

+0

Gracias por la captura de eso. He actualizado mi respuesta. –