how to extend an instance of visual class: was using RADs in OO way

Serge Boiko boiko at demogr.mpg.de
Thu May 22 17:28:33 EDT 2003


Hi there,
I decided to start a new thread because, obviously I was not very presice
in my previous posting. Perhaps the subject line was confusing. 

Let me give a code example that could clarify my point.
I create a code for a very simple PyQt application, but usage of this
library doesn't matter here. I used Qt Designer -- a very nice and powerful
RAD for C++/Python. Designer generated a code that I put in the module
called form1 (attached to the end of this message). Then I created a
code that is called form2.py and it is shown below:

from form1 import *

class Form2(Form1):
    def __init__(self, *args):
        Form1.__init__(self, *args)
        self.setCaption("Form2")
        #self.pushButton1=MyButton(self, "pushButton2")

class MyButton(QPushButton):
    def __init__(self, *args):
        QPushButton.__init__(self, *args)
        self.setText("Button2")

if __name__ == "__main__":
    a = QApplication(sys.argv)
    QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()"))
    w = Form2()
    a.setMainWidget(w)
    w.show()
    a.exec_loop()

What's going on here? I created a new class Form2 that inherits from
class Form 1 defined in the module form1 and modify it here, changing
the form caption. Let's imagine that one day I decided that functionality
provided by QPushButton is not sufficient for my needs. So I create
class MyButton derived from QPushButton that somehow modifies its
behavior. I cannot simply add line 

self.pushButton1=MyButton(self, "pushButton2")

because if do this I loose all settings of pushButton1, so I actually
have to put this line into module form1. But this is not an especially
good idea, because form1.py is machine generated code and all manual
modifications will be lost when I open this code in the IDE next
time. 

Obviously code refactoring could help in this situation but I have to
use some automatic tool for that, unfortunately I don't have one. So
my question: is there any elegant strategy for the situation like
that?

I attached my previous posting for references. The contents of form1.py
goes below:


import sys
from qt import *


class Form1(QDialog):
    def __init__(self,parent = None,name = None,modal = 0,fl = 0):
        QDialog.__init__(self,parent,name,modal,fl)

        if not name:
            self.setName("Form1")


        Form1Layout = QGridLayout(self,1,1,11,6,"Form1Layout")

        self.pushButton1 = QPushButton(self,"pushButton1")

        Form1Layout.addWidget(self.pushButton1,0,0)

        self.languageChange()

        self.resize(QSize(124,52).expandedTo(self.minimumSizeHint()))

    def languageChange(self):
        self.setCaption(self.tr("Form1"))
        self.pushButton1.setText(self.tr("Button1"))


if __name__ == "__main__":
    a = QApplication(sys.argv)
    QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()"))
    w = Form1()
    a.setMainWidget(w)
    w.show()
    a.exec_loop()

Many thanks, 
-Serge


Here is my previous posting:

Hi Many thanks, 
-Sergethere,
I have a question regarding the usage of IDE/RAD tools with Python, but the
problem might be more general and equally can be applied to any
language (see Allen Holub's notes on IDE/RADs for Java:
http://www.javaworld.com/javaworld/jw-07-1999/jw-07-toolbox.html). 

When I use IDE/RAD I can easily create a GUI for my
application. Initially this GUI may consist of the standard components
provided by my IDE of choice. Usually I don't edit the code created by IDE
directly.  Instead I subclass the container class (i.e. the
application skeleton) and fill it with the contents and functionality
I want.  This gives me an important flexibility: I don't have to
change my code if I modified a file created by the RAD tool. Put it
another way: any cosmetic changes of my application don't affect the
functional part, these parts live in separate modules.

This approach works fine if I use *STANDARD* components. But what if
instead of plain standard button presented by the class StandardButton
I want to use a button of the class MyButton derived from
StandardButton and my RAD doesn't provide facilities to add custom
widgets written in Python? Surely, I could remove an instance of the
StandardButton from the container widget and replace it with an
instance of MyButton (again in the module that contains my
functionality and is not generated by the RAD). This approach is not
applicable to every situation, however. For complex layouts it may
cause unpredictable results. An alternative solution is to extend
functionality of the StandardButton dynamically adding/overriding
methods of StandardButton at runtime. See recipe 5.12 in the Python
Cookbook. It works if we need to modify our base class functionality
only slightly.

More general approach would be to use some refactoring techniques but
it implies that my IDE supports them. By the way is there any IDE that
can do that?

So my question is: how to deal with such a situation in an
object-oriented and reusable way, to separate RAD generated code for
manually coded stuff? 

If these words are too abstract I could give a simple Python example.

Many thanks and looking forward to hearing from you, Python gurus!
-Serge










More information about the Python-list mailing list