~richardjones/withgui/trunk

« back to all changes in this revision

Viewing changes to withqt4.py

  • Committer: Richard Jones
  • Date: 2009-08-27 05:57:06 UTC
  • Revision ID: richard@l-rjones.off.ekorp.com-20090827055706-rm3nnqy4sonkot95
reorg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import sys
2
 
 
3
 
import PyQt4.Qt as qt
4
 
 
5
 
import withgui
6
 
 
7
 
class GUI(object):
8
 
    def __init__(self, app):
9
 
        self.app = app
10
 
 
11
 
    def run(self):
12
 
        self.app.exec_()
13
 
 
14
 
    def stop(self, data=None):
15
 
        self.app.quit()
16
 
        return data
17
 
 
18
 
class WidgetWrapper(object):
19
 
    '''Wrapper around a Tkinter widget and optionally a separate Tkinter
20
 
    variable allowing read/write access to the widget's properties
21
 
    including its current value.
22
 
    '''
23
 
    def __init__(self, widget, variable):
24
 
        self.widget = widget
25
 
        self.variable = variable
26
 
    def set_property(self, name, value):
27
 
        if name == 'value':
28
 
            self.variable.set(value)
29
 
        else:
30
 
            # XXX check this is correct?
31
 
            setattr(self.widget, name, value)
32
 
    def get_property(self, name):
33
 
        if name == 'value':
34
 
            return self.variable.get()
35
 
        else:
36
 
            return getattr(self.widget, name)
37
 
 
38
 
# mapping withgui properties to Tkinter properties
39
 
prop_passthrough = lambda v: v
40
 
prop_color = lambda v: '#'+v.to_hex()
41
 
properties = dict(
42
 
    justify=('justify', prop_passthrough),
43
 
    foreground=('foreground', prop_color),
44
 
    background=('background', prop_color),
45
 
    value=('value', prop_passthrough),
46
 
)
47
 
label_properties = dict(
48
 
    value=('text', prop_passthrough),
49
 
)
50
 
text_properties = dict(
51
 
    value=('text', prop_passthrough),
52
 
)
53
 
def generate_properties(node, override):
54
 
    d = {}
55
 
    for k,v in node.defaults.items():
56
 
        if k in override:
57
 
            k, p = override[k]
58
 
        else:
59
 
            k, p = properties[k]
60
 
        d[k] = p(v)
61
 
    return d
62
 
 
63
 
class Constructor(object):
64
 
    def construct(self, node, parent=None):
65
 
        adder = getattr(self, 'add_%s'%node.__class__.__name__)
66
 
        w = adder(node, parent)
67
 
        return w
68
 
 
69
 
    def add_Window(self, node, parent):
70
 
        self.app = qt.QApplication(sys.argv[:1])
71
 
        self.app.setQuitOnLastWindowClosed(True)
72
 
        c = self.construct(node.children[0])
73
 
        c.setMinimumSize(200, 100)
74
 
        c.show()
75
 
        return GUI(self.app)
76
 
 
77
 
    def add_Vertical(self, node, parent):
78
 
        layout = QVBoxLayout(parent)
79
 
        for child in node.children:
80
 
            self.construct(child, layout)
81
 
        return layout
82
 
 
83
 
    def add_Label(self, node, parent, **kw):
84
 
        label = qt.QLabel()
85
 
        kw = generate_properties(node, label_properties)
86
 
        label.setText(kw.pop('text'))
87
 
        node.implementation = WidgetWrapper(label, label)
88
 
        return label
89
 
 
90
 
    def add_Form(self, node, parent):
91
 
        frame = tk.Frame(parent)
92
 
        frame._form = {}
93
 
        for n, row in enumerate(node.rows):
94
 
            label = ''
95
 
            if row.label is not None:
96
 
                l = self.add_Label(row.label, frame, justify=tk.RIGHT)
97
 
                l.grid(row=n, column=0, sticky=tk.E)
98
 
                label = row.label.value
99
 
 
100
 
            if row.widget is not None:
101
 
                # figure the name for this widget in the form
102
 
                w = self.construct(row.widget, frame)
103
 
                w.grid(row=n, column=1, sticky=tk.W)
104
 
 
105
 
            if row.help is not None:
106
 
                l = self.add_Label(row.help, frame, justify=tk.LEFT)
107
 
                l.grid(row=n, column=2, sticky=tk.W)
108
 
 
109
 
        bframe = tk.Frame(frame)
110
 
        for button in node.buttons:
111
 
            w = self.construct(button, bframe)
112
 
            w.pack(side=tk.LEFT)
113
 
 
114
 
        bframe.grid(row=n+1, column=1, columnspan=2, sticky=tk.W)
115
 
        return frame
116
 
 
117
 
    def add_Text(self, node, parent):
118
 
        kw = generate_properties(node, label_properties)
119
 
        w = tk.Entry(parent, **kw)
120
 
        node.implementation = WidgetWrapper(w, w)
121
 
        return w
122
 
 
123
 
    def add_Selection(self, node, parent):
124
 
        kw = generate_properties(node, {})
125
 
        var = tk.StringVar(parent)
126
 
        value = kw.pop('value')
127
 
        var.set(value[0])
128
 
        args = (parent, var) + tuple(value)
129
 
        option = tk.OptionMenu(*args, **kw)
130
 
        node.implementation = WidgetWrapper(option, var)
131
 
        return option
132
 
 
133
 
    def add_Help(self, node, parent):
134
 
        return self.add_Label(node, parent)
135
 
 
136
 
    def add_Button(self, node, parent):
137
 
        kw = generate_properties(node, label_properties)
138
 
        label = kw.pop('text')
139
 
        w = qt.QPushButton(label, parent)
140
 
        self.app.connect(w, qt.SIGNAL("clicked()"), node.event_handlers.get('on_click'))
141
 
        node.implementation = WidgetWrapper(w, w)
142
 
        return w
143
 
    add_Submit = add_Button
144
 
    add_Cancel = add_Button
145
 
 
146