]>
Commit | Line | Data |
---|---|---|
be05b434 RD |
1 | """ |
2 | This sample shows how to put multiple objects in the clipboard, one of | |
3 | which uses a custom data format. In this case we use a Python | |
4 | dictionary of values for our custom format, and we also put a textual | |
5 | representation of the dictionary. To test this, run two instances of | |
6 | this program, enter data in one and click the copy button. Then click | |
7 | the paste button in the other instance. Also paste into a text editor | |
8 | to see the data in the standard text format. | |
9 | """ | |
10 | ||
11 | ||
12 | import wx | |
13 | import cPickle | |
14 | import pprint | |
15 | ||
16 | class TestFrame(wx.Frame): | |
17 | def __init__(self): | |
18 | wx.Frame.__init__(self, None, -1, "Copy/Paste Test") | |
19 | panel = wx.Panel(self) | |
20 | ||
21 | # First create the controls | |
22 | topLbl = wx.StaticText(panel, -1, "Account Information") | |
23 | topLbl.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD)) | |
24 | ||
25 | nameLbl = wx.StaticText(panel, -1, "Name:") | |
26 | self.name = wx.TextCtrl(panel, -1, ""); | |
27 | ||
28 | addrLbl = wx.StaticText(panel, -1, "Address:") | |
29 | self.addr1 = wx.TextCtrl(panel, -1, ""); | |
30 | self.addr2 = wx.TextCtrl(panel, -1, ""); | |
31 | ||
32 | cstLbl = wx.StaticText(panel, -1, "City, State, Zip:") | |
33 | self.city = wx.TextCtrl(panel, -1, "", size=(150,-1)); | |
34 | self.state = wx.TextCtrl(panel, -1, "", size=(50,-1)); | |
35 | self.zip = wx.TextCtrl(panel, -1, "", size=(70,-1)); | |
36 | ||
37 | phoneLbl = wx.StaticText(panel, -1, "Phone:") | |
38 | self.phone = wx.TextCtrl(panel, -1, ""); | |
39 | ||
40 | emailLbl = wx.StaticText(panel, -1, "Email:") | |
41 | self.email = wx.TextCtrl(panel, -1, ""); | |
42 | ||
43 | copyBtn = wx.Button(panel, -1, "Copy") | |
44 | pasteBtn = wx.Button(panel, -1, "Paste") | |
45 | self.Bind(wx.EVT_BUTTON, self.OnCopy, copyBtn) | |
46 | self.Bind(wx.EVT_BUTTON, self.OnPaste, pasteBtn) | |
47 | ||
48 | # Now do the layout. | |
49 | ||
50 | # mainSizer is the top-level one that manages everything | |
51 | mainSizer = wx.BoxSizer(wx.VERTICAL) | |
52 | mainSizer.Add(topLbl, 0, wx.ALL, 5) | |
53 | mainSizer.Add(wx.StaticLine(panel), 0, | |
54 | wx.EXPAND|wx.TOP|wx.BOTTOM, 5) | |
55 | ||
56 | # addrSizer is a grid that holds all of the address info | |
57 | addrSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5) | |
58 | addrSizer.AddGrowableCol(1) | |
59 | addrSizer.Add(nameLbl, 0, | |
60 | wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) | |
61 | addrSizer.Add(self.name, 0, wx.EXPAND) | |
62 | addrSizer.Add(addrLbl, 0, | |
63 | wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) | |
64 | addrSizer.Add(self.addr1, 0, wx.EXPAND) | |
65 | addrSizer.Add((10,10)) # some empty space | |
66 | addrSizer.Add(self.addr2, 0, wx.EXPAND) | |
67 | ||
68 | addrSizer.Add(cstLbl, 0, | |
69 | wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) | |
70 | ||
71 | # the city, state, zip fields are in a sub-sizer | |
72 | cstSizer = wx.BoxSizer(wx.HORIZONTAL) | |
73 | cstSizer.Add(self.city, 1) | |
74 | cstSizer.Add(self.state, 0, wx.LEFT|wx.RIGHT, 5) | |
75 | cstSizer.Add(self.zip) | |
76 | addrSizer.Add(cstSizer, 0, wx.EXPAND) | |
77 | ||
78 | addrSizer.Add(phoneLbl, 0, | |
79 | wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) | |
80 | addrSizer.Add(self.phone, 0, wx.EXPAND) | |
81 | addrSizer.Add(emailLbl, 0, | |
82 | wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) | |
83 | addrSizer.Add(self.email, 0, wx.EXPAND) | |
84 | ||
85 | # now add the addrSizer to the mainSizer | |
86 | mainSizer.Add(addrSizer, 0, wx.EXPAND|wx.ALL, 10) | |
87 | ||
88 | # The buttons sizer will put them in a row with resizeable | |
89 | # gaps between and on either side of the buttons | |
90 | btnSizer = wx.BoxSizer(wx.HORIZONTAL) | |
91 | btnSizer.Add((20,20), 1) | |
92 | btnSizer.Add(copyBtn) | |
93 | btnSizer.Add((20,20), 1) | |
94 | btnSizer.Add(pasteBtn) | |
95 | btnSizer.Add((20,20), 1) | |
96 | ||
97 | mainSizer.Add(btnSizer, 0, wx.EXPAND|wx.BOTTOM, 10) | |
98 | ||
99 | panel.SetSizer(mainSizer) | |
100 | ||
101 | # Fit the frame to the needs of the sizer. The frame will | |
102 | # automatically resize the panel as needed. Also prevent the | |
103 | # frame from getting smaller than this size. | |
104 | mainSizer.Fit(self) | |
105 | self.SetMinSize(self.GetSize()) | |
106 | ||
107 | ||
108 | fieldNames = ["name", "addr1", "addr2", | |
109 | "city", "state", "zip", "phone", "email"] | |
110 | ||
111 | def OnCopy(self, evt): | |
112 | # make a dictionary of values | |
113 | fieldData = {} | |
114 | for name in self.fieldNames: | |
115 | tc = getattr(self, name) | |
116 | fieldData[name] = tc.GetValue() | |
117 | ||
118 | # pickle it and put in a custom data object | |
119 | cdo = wx.CustomDataObject("ContactDictFormat") | |
120 | cdo.SetData(cPickle.dumps(fieldData)) | |
121 | ||
122 | # also make a text representaion | |
123 | tdo = wx.TextDataObject(pprint.pformat(fieldData)) | |
124 | ||
125 | # and put them both in the clipboard | |
126 | dataobj = wx.DataObjectComposite() | |
127 | dataobj.Add(cdo) | |
128 | dataobj.Add(tdo) | |
129 | if wx.TheClipboard.Open(): | |
130 | wx.TheClipboard.SetData(dataobj) | |
131 | wx.TheClipboard.Close() | |
132 | ||
133 | ||
134 | def OnPaste(self, evt): | |
135 | # Get the custom format object and put it into | |
136 | # the entry fields | |
137 | cdo = wx.CustomDataObject("ContactDictFormat") | |
138 | if wx.TheClipboard.Open(): | |
139 | success = wx.TheClipboard.GetData(cdo) | |
140 | wx.TheClipboard.Close() | |
141 | if success: | |
142 | data = cdo.GetData() | |
143 | fieldData = cPickle.loads(data) | |
144 | for name in self.fieldNames: | |
145 | tc = getattr(self, name) | |
146 | tc.SetValue(fieldData[name]) | |
147 | ||
148 | ||
149 | ||
150 | app = wx.PySimpleApp() | |
151 | TestFrame().Show() | |
152 | app.MainLoop() |