be422afd pyros2097

13 years ago
Save
Files changed (3) hide show
  1. Widget/LexerSquirrel.py +186 -0
  2. Widget/editor.py +41 -21
  3. Widget/keylex.py +328 -0
Widget/LexerSquirrel.py ADDED
@@ -0,0 +1,186 @@
1
+ from PyQt4.Qsci import QsciLexerCustom,QsciStyle
2
+ from PyQt4.QtCore import QString
3
+ from PyQt4.QtGui import *
4
+
5
+ #class QsciLexerSquirrel(QsciLexer):
6
+
7
+ # def __init__(self):
8
+ # pass
9
+ #prefs.declare('font.name.margin', "MS Dlg")
10
+ #prefs.declare('font.size.margin', 8)
11
+ #prefs.declare('font.name.code', "Courier New")
12
+ #prefs.declare('font.size.code', 10)
13
+ #prefs.declare('color.editline', "#d0e0ff")
14
+
15
+ class QsciLexerSquirrel(QsciLexerCustom):
16
+ def __init__(self, obj=None):
17
+ QsciLexerCustom.__init__(self, obj)
18
+ self.sci = None
19
+ self.plainFont = QFont()
20
+ self.plainFont.setPointSize(10)
21
+ self.plainFont.setFamily("Courier New")
22
+ self.marginFont = QFont()
23
+ self.marginFont.setPointSize(10)
24
+ self.marginFont.setFamily("MS Dlg")
25
+ self.boldFont = QFont()
26
+ self.boldFont.setPointSize(10)
27
+ self.boldFont.setFamily("Courier New")
28
+ self.boldFont.setBold(True)
29
+ self.styles = [
30
+ QsciStyle(0, QString("base"), QColor("#000000"), QColor("#ffffff"), self.plainFont, True),
31
+ QsciStyle(1, QString("comment"), QColor("#008000"), QColor("#eeffee"), self.marginFont, True),
32
+ QsciStyle(2, QString("keyword"), QColor("#000080"), QColor("#ffffff"), self.boldFont, True),
33
+ QsciStyle(3, QString("string"), QColor("#800000"), QColor("#ffffff"), self.marginFont, True),
34
+ QsciStyle(4, QString("atom"), QColor("#008080"), QColor("#ffffff"), self.plainFont, True),
35
+ QsciStyle(5, QString("macro"), QColor("#808000"), QColor("#ffffff"), self.boldFont, True),
36
+ QsciStyle(6, QString("error"), QColor("#000000"), QColor("#ffd0d0"), self.plainFont, True),
37
+ ]
38
+ print("LexerErlang created")
39
+
40
+ def description(self, ix):
41
+ for i in self.styles:
42
+ if i.style() == ix:
43
+ return QtCore.QString(i.description())
44
+ return QtCore.QString("")
45
+ def setEditor(self, sci):
46
+ self.sci = sci
47
+ Qsci.QsciLexerCustom.setEditor(self, sci)
48
+ print("LexerErlang.setEditor()")
49
+ def styleText(self, start, end):
50
+ print("LexerErlang.styleText(%d,%d)" % (start, end))
51
+ lines = self.getText(start, end)
52
+ offset = start
53
+ self.startStyling(offset, 0)
54
+ print("startStyling()")
55
+ for i in lines:
56
+ if i == "":
57
+ self.setStyling(1, self.styles[0])
58
+ print("setStyling(1)")
59
+ offset += 1
60
+ continue
61
+ if i[0] == '%':
62
+ self.setStyling(len(i)+1, self.styles[1])
63
+ print("setStyling(%)")
64
+ offset += len(i)+1
65
+ continue
66
+ self.setStyling(len(i)+1, self.styles[0])
67
+ print("setStyling(n)")
68
+ offset += len(i)+1
69
+
70
+ def getText(self, start, end):
71
+ data = self.sci.text()
72
+ print("LexerErlang.getText(): " + str(len(data)) + " chars")
73
+ return data[start:end].split('\n')
74
+
75
+
76
+ import sys
77
+ from PyQt4 import QtCore, QtGui, Qsci
78
+
79
+ class MainWindow(QtGui.QMainWindow):
80
+ def __init__(self):
81
+ QtGui.QMainWindow.__init__(self)
82
+ self.setWindowTitle('Custom Lexer Example')
83
+ self.setGeometry(QtCore.QRect(50,200,400,400))
84
+ self.editor = Qsci.QsciScintilla(self)
85
+ self.editor.setUtf8(True)
86
+ self.editor.setMarginWidth(2, 15)
87
+ self.editor.setFolding(True)
88
+ self.setCentralWidget(self.editor)
89
+ self.lexer = CustomLexer(self.editor)
90
+ self.editor.setLexer(self.lexer)
91
+ self.editor.setText('\n# sample source\n\nfoo = 1\nbar = 2\n')
92
+
93
+ class CustomLexer(Qsci.QsciLexerCustom):
94
+ def __init__(self, parent):
95
+ Qsci.QsciLexerCustom.__init__(self, parent)
96
+ self._styles = {
97
+ 0: 'Default',
98
+ 1: 'Comment',
99
+ 2: 'Key',
100
+ 3: 'Assignment',
101
+ 4: 'Value',
102
+ }
103
+ for key,value in self._styles.iteritems():
104
+ setattr(self, value, key)
105
+
106
+ def description(self, style):
107
+ return self._styles.get(style, '')
108
+
109
+ def defaultColor(self, style):
110
+ if style == self.Default:
111
+ return QtGui.QColor('#000000')
112
+ elif style == self.Comment:
113
+ return QtGui.QColor('#C0C0C0')
114
+ elif style == self.Key:
115
+ return QtGui.QColor('#0000CC')
116
+ elif style == self.Assignment:
117
+ return QtGui.QColor('#CC0000')
118
+ elif style == self.Value:
119
+ return QtGui.QColor('#00CC00')
120
+ return Qsci.QsciLexerCustom.defaultColor(self, style)
121
+
122
+ def styleText(self, start, end):
123
+ editor = self.editor()
124
+ if editor is None:
125
+ return
126
+
127
+ # scintilla works with encoded bytes, not decoded characters.
128
+ # this matters if the source contains non-ascii characters and
129
+ # a multi-byte encoding is used (e.g. utf-8)
130
+ source = ''
131
+ if end > editor.length():
132
+ end = editor.length()
133
+ if end > start:
134
+ if sys.hexversion >= 0x02060000:
135
+ # faster when styling big files, but needs python 2.6
136
+ source = bytearray(end - start)
137
+ editor.SendScintilla(
138
+ editor.SCI_GETTEXTRANGE, start, end, source)
139
+ else:
140
+ source = unicode(editor.text()
141
+ ).encode('utf-8')[start:end]
142
+ if not source:
143
+ return
144
+
145
+ # the line index will also be needed to implement folding
146
+ index = editor.SendScintilla(editor.SCI_LINEFROMPOSITION, start)
147
+ if index > 0:
148
+ # the previous state may be needed for multi-line styling
149
+ pos = editor.SendScintilla(
150
+ editor.SCI_GETLINEENDPOSITION, index - 1)
151
+ state = editor.SendScintilla(editor.SCI_GETSTYLEAT, pos)
152
+ else:
153
+ state = self.Default
154
+
155
+ set_style = self.setStyling
156
+ self.startStyling(start, 0x1f)
157
+
158
+ # scintilla always asks to style whole lines
159
+ for line in source.splitlines(True):
160
+ length = len(line)
161
+ if line.startswith('#'):
162
+ state = self.Comment
163
+ else:
164
+ # the following will style lines like "x = 0"
165
+ pos = line.find('=')
166
+ if pos > 0:
167
+ set_style(pos, self.Key)
168
+ set_style(1, self.Assignment)
169
+ length = length - pos - 1
170
+ state = self.Value
171
+ else:
172
+ state = self.Default
173
+ set_style(length, state)
174
+ # folding implementation goes here
175
+ levelFolder = editor.SendScintilla(editor.SCI_GETFOLDLEVEL, index-1)
176
+ if line.startswith('+ '):
177
+ editor.SendScintilla(editor.SCI_SETFOLDLEVEL, index, levelFolder + 1)
178
+ index += 1
179
+
180
+ if __name__ == "__main__":
181
+ app = QtGui.QApplication(sys.argv)
182
+ app.connect(app, QtCore.SIGNAL('lastWindowClosed()'),
183
+ QtCore.SLOT('quit()'))
184
+ win = MainWindow()
185
+ win.show()
186
+ sys.exit(app.exec_())
Widget/editor.py CHANGED
@@ -3,36 +3,40 @@ from PyQt4.QtGui import QFontMetrics, QFont, QPixmap, QColor,
3
3
  from PyQt4.Qsci import QsciScintilla, QsciLexerPython ,QsciAPIs
4
4
  from globals import ospathjoin,workDir,fontSize,fontName
5
5
 
6
- class Editor(QsciScintilla):
7
- ARROW_MARKER_NUM = 8
8
6
 
7
+ class Style:
9
- def __init__(self,parent,text):
8
+ def __init__(self):
9
+ self.font = QColor('#000000')
10
- super(Editor, self).__init__(parent)
10
+ self.paper = QColor('#FFFFFF')
11
- self.parent = parent
11
+ self.caret = QColor('#FFFFFF')
12
+ self.marker = QColor('#ffe4e4')
13
+ self.margin = QColor('#cccccc')
12
- font = QFont()
14
+ self.font = QFont()
13
- font.setFamily(fontName)
15
+ self.font.setFamily(fontName)
14
- font.setFixedPitch(True)
16
+ self.font.setFixedPitch(True)
15
- font.setPointSize(fontSize)
17
+ self.font.setPointSize(fontSize)
16
- self.setFont(font)
18
+
17
19
  self.setMarginsFont(font)
18
20
  self.setText(text)
21
+
22
+
23
+ class Editor(QsciScintilla):
24
+ ARROW_MARKER_NUM = 8
25
+ def __init__(self,parent,text,styleIndex = 0):
26
+ QsciScintilla.__init__(self,parent)
27
+ self.parent = parent
28
+ self.styleIndex = styleIndex
29
+ self.colorSyle = None
30
+
19
31
  #self.addAction(QAction("gg",self))
20
32
  #self.findFirst("function",False,True,True,True)
21
33
  #self.setEdgeColumn(70)
22
34
  #self.setEdgeColor(QColor(0,0,0))
23
- #self.setEdgeMode(self.EDGE_LINE)
35
+ #self.setEdgeMode(self.EDGE_LINE)
24
- # Margin 0 is used for line numbers
25
- fontmetrics = QFontMetrics(font)
26
- self.setMarginsFont(font)
27
- self.setMarginWidth(0, fontmetrics.width("00000") + 6)
28
- self.setMarginLineNumbers(0, True)
29
- self.setMarginsBackgroundColor(QColor("#cccccc"))
30
-
31
36
  # Clickable margin 1 for showing markers
32
37
  self.setMarginSensitivity(1, True)
33
38
  self.connect(self,SIGNAL('marginClicked(int, int, Qt::KeyboardModifiers)'),self.on_margin_clicked)
34
39
  self.markerDefine(QsciScintilla.RightArrow,self.ARROW_MARKER_NUM)
35
- self.setMarkerBackgroundColor(QColor("#ee1111"),self.ARROW_MARKER_NUM)
36
40
  self.registerImage(0,QPixmap(":/Icons/class_obj.gif"))
37
41
  self.registerImage(1,QPixmap(":/Icons/method_obj.gif"))
38
42
  self.registerImage(2,QPixmap(":/Icons/field_public_obj.gif"))
@@ -45,8 +49,6 @@ class Editor(QsciScintilla):
45
49
 
46
50
  # Current line visible with special background color
47
51
  self.setCaretLineVisible(True)
48
- self.setCaretLineBackgroundColor(QColor("#ffe4e4"))
49
-
50
52
 
51
53
  self.lexer = QsciLexerPython()
52
54
  #print ospathjoin(workDir,"emo.api")
@@ -62,7 +64,25 @@ class Editor(QsciScintilla):
62
64
  #self.setAutoCompletionSource(QsciScintilla.AcsAll)
63
65
  #self.SendScintilla(QsciScintilla.SCI_STYLESETFONT, 1, 'Courier')
64
66
 
67
+ def init(self):
68
+ self.setColorStyle(self.styleIndex)
69
+ self.font = self.colorSyle.font
70
+ self.setFont(self.font)
71
+ self.fontmetrics = QFontMetrics(self.font)
72
+ self.setMarginsFont(self.font)
73
+ self.setMarginWidth(0, self.fontmetrics.width("00000") + 6)
74
+ # Margin 0 is used for line numbers
75
+ self.setMarginLineNumbers(0, True)
76
+
65
77
  def setColorStyle(self,styleIndex):
78
+ if styleIndex == 0:
79
+ self.colorSyle = Style()
80
+ elif styleIndex == 1:
81
+ self.colorSyle = Style1()
82
+ self.setCaretLineBackgroundColor()
83
+ self.setMarginsBackgroundColor()
84
+ self.setMarkerBackgroundColor(QColor("#ee1111"),self.ARROW_MARKER_NUM)
85
+
66
86
 
67
87
 
68
88
 
Widget/keylex.py ADDED
@@ -0,0 +1,328 @@
1
+ import sys
2
+ from PyQt4.QtCore import SIGNAL, SLOT, QString,QStringList
3
+ from PyQt4.QtGui import QApplication, QMainWindow, QColor, QFont
4
+ from PyQt4.Qsci import QsciScintilla, QsciLexerCustom, QsciStyle
5
+
6
+ _sample = """
7
+ This example shows how to highlight some specific lines or words.
8
+
9
+ + A first level title bold and red
10
+ + A secund level title bold and blue with a yellow background
11
+ Some text with green in green but also bold and underlined.
12
+ The digits are gray with an orange backround. You don't believe it, look at that : 1 , 2 , ... , 123456789...
13
+
14
+ It's very uggly but it shows how to do more pretty "highlighters".
15
+
16
+ /*
17
+ * credit scene
18
+ */
19
+ class CreditScene {
20
+ foreground = null;
21
+ okButton = null;
22
+ layer = null;
23
+
24
+ fadingOut = false;
25
+
26
+ function onLoad() {
27
+ stage.bgcolor(0, 0, 0, 1);
28
+
29
+ local stageCenterX = stage.getWindowWidth() * 0.5;
30
+ local stageCenterY = stage.getWindowHeight() * 0.5;
31
+
32
+ local bgWidth = 480;
33
+ local bgHeight = 320;
34
+
35
+ if (useHD) {
36
+ bgWidth = 960;
37
+ bgHeight = 640;
38
+ }
39
+
40
+ if (background != null) {
41
+ background.remove();
42
+ }
43
+
44
+ background = emo.Sprite(getHdImageName("credit_background.png"));
45
+ background.moveCenter(stageCenterX, stageCenterY);
46
+ background.setZ(0);
47
+ background.load();
48
+
49
+ layer = emo.Rectangle();
50
+ layer.setSize(stage.getWindowWidth(), stage.getWindowHeight());
51
+ layer.color(0.5, 0.5, 0.5, 0.78);
52
+ layer.setZ(1);
53
+ layer.load();
54
+
55
+ foreground = emo.SpriteSheet(getHdImageName("credit.png"), bgWidth, bgHeight);
56
+ foreground.moveCenter(stageCenterX, stageCenterY);
57
+ foreground.setZ(2);
58
+ foreground.load();
59
+
60
+ foreground.animate(0, 2, 200, -1);
61
+
62
+ local btWidth = 159;
63
+ local btHeight = 52;
64
+
65
+ if (useHD) {
66
+ btWidth = 318;
67
+ btHeight = 104;
68
+ }
69
+
70
+ okButton = emo.SpriteSheet(getHdImageName("credit_button.png"), btWidth, btHeight);
71
+ okButton.move(
72
+ foreground.getX() + foreground.getWidth() - okButton.getWidth(),
73
+ foreground.getY() + foreground.getHeight() - okButton.getHeight());
74
+ okButton.setZ(3);
75
+ okButton.load();
76
+ okButton.setFrame(1);
77
+ }
78
+
79
+ /*
80
+ * Called when the app has gained focus
81
+ */
82
+ function onGainedFocus() {
83
+ audio.playBGM();
84
+ }
85
+
86
+ /*
87
+ * Called when the app has lost focus
88
+ */
89
+ function onLostFocus() {
90
+ audio.pauseBGM();
91
+ }
92
+
93
+ function onDispose() {
94
+ okButton.remove();
95
+ foreground.remove();
96
+ layer.remove();
97
+ background.remove();
98
+
99
+ background = null;
100
+ }
101
+
102
+ /*
103
+ * touch event
104
+ */
105
+ function onMotionEvent(mevent) {
106
+ local x = mevent.getX();
107
+ local y = mevent.getY();
108
+ if (mevent.getAction() == MOTION_EVENT_ACTION_DOWN) {
109
+ if (okButton.contains(x, y)) {
110
+ okButton.setFrame(0);
111
+ audio.playSE0();
112
+ if (!fadingOut) {
113
+ fadingOut = true;
114
+ stage.load(TitleScene(),
115
+ null, emo.AlphaModifier(0, 1, 500, emo.easing.CubicOut));
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ """
123
+ class MainWindow(QMainWindow):
124
+ def __init__(self):
125
+ QMainWindow.__init__(self)
126
+ self.setWindowTitle('Custom Lexer For Config Files')
127
+ self.setGeometry(50, 200, 400, 400)
128
+ self.editor = QsciScintilla(self)
129
+ self.editor.setUtf8(True)
130
+
131
+ # LINES' NUMBER IN THE MARGIN
132
+ self.editor.setMarginLineNumbers(1,True)
133
+ self.editor.setMarginWidth(1, QString("-------"))
134
+ # OK for 3 digits. This was found by direct tests...
135
+ # WRAPING
136
+ self.editor.setWrapMode(True)
137
+ self.setCentralWidget(self.editor)
138
+ self.lexer = ConfigLexer(self.editor)
139
+ self.editor.setLexer(self.lexer)
140
+ self.editor.setText(_sample)
141
+
142
+
143
+ class ConfigLexer(QsciLexerCustom):
144
+ def __init__(self, parent):
145
+ QsciLexerCustom.__init__(self, parent)
146
+ self._styles = {
147
+ 0: 'Default',
148
+ 1: 'FirstLevelTitle',
149
+ 2: 'SecundLevelTitle',
150
+ 3: 'Green',
151
+ 4: 'Digits',
152
+ 5: 'KeyWord1',
153
+ 6: 'KeyWord2',
154
+ 7: 'KeyWord3',
155
+ 8: 'KeyWord4',
156
+ }
157
+ for key,value in self._styles.iteritems():
158
+ setattr(self, value, key)
159
+
160
+ self.words1 = [
161
+ 'base','break','case','catch','class','clone',
162
+ 'continue','const','default','delete','else','enum',
163
+ 'extends','for','foreach','function','if','in',
164
+ 'local','null','resume','return','switch','this',
165
+ 'throw','try','typeof','while','yield','constructor',
166
+ 'instanceof','true','false','static'
167
+ ]
168
+
169
+ self.words2 = [
170
+ 'init', 'dest', 'onLoad', 'onDispose', 'onGainedFocus','onMotionEvent',
171
+ 'onLostFocus','onUpdate','onFps','onKeyEvent','onSensorEvent',
172
+ 'onControlEvent','onDrawFrame','onError','onLowMemory','onNetCallBack'
173
+ ]
174
+
175
+ self.words3 = [
176
+ 'rawdelete', 'rawin', 'array', 'seterrorhandler', 'setdebughook',
177
+ 'enabledebuginfo', 'getroottable', 'setroottable', 'getconsttable',
178
+ 'setconsttable', 'assert', 'print', 'compilestring', 'collectgarbage',
179
+ 'type', 'getstackinfos', 'newthread', 'tofloat', 'tostring',
180
+ 'tointeger', 'tochar', 'weakref', 'slice', 'find', 'tolower',
181
+ 'toupper', 'len', 'rawget', 'rawset', 'clear', 'append', 'push',
182
+ 'extend', 'pop', 'top', 'insert', 'remove', 'resize', 'sort',
183
+ 'reverse', 'call', 'pcall', 'acall', 'pacall', 'bindenv', 'instance',
184
+ 'getattributes', 'getclass', 'getstatus', 'ref'
185
+ ]
186
+
187
+ self.words4 = [
188
+ ]
189
+
190
+
191
+
192
+ def language(self):
193
+ return 'Squirrel'
194
+
195
+ def foldCompact(self):
196
+ return self._foldcompact
197
+
198
+ def setFoldCompact(self, enable):
199
+ self._foldcompact = bool(enable)
200
+
201
+ def description(self, style):
202
+ return self._styles.get(style, '')
203
+
204
+ def defaultColor(self, style):
205
+ if style == self.Default:
206
+ return QColor('#000000')
207
+ elif style == self.FirstLevelTitle:
208
+ return QColor('#FF0000')
209
+ elif style == self.SecundLevelTitle:
210
+ return QColor('#0000FF')
211
+ elif style == self.Green:
212
+ return QColor('#00FF00')
213
+ elif style == self.Digits:
214
+ return QColor('#AAAAAA')
215
+ elif style == self.KeyWord1:
216
+ return QColor('#8000FF')
217
+ elif style == self.KeyWord2:
218
+ return QColor('#400080')
219
+ elif style == self.KeyWord3:
220
+ return QColor('#FF0000')
221
+ elif style == self.KeyWord4:
222
+ return QColor('#000000')
223
+
224
+ return QsciLexerCustom.defaultColor(self, style)
225
+
226
+ def defaultFont(self, style):
227
+ font = QsciLexerCustom.defaultFont(self, style)
228
+
229
+ if style == self.FirstLevelTitle or style == self.SecundLevelTitle:
230
+ font.setBold(True)
231
+ elif style == self.Green:
232
+ font.setBold(True)
233
+ font.setUnderline(True)
234
+
235
+ return font
236
+
237
+ def defaultPaper(self, style):
238
+ # Here we change the color of the background.
239
+ # We want to colorize all the background of the line.
240
+ # This is done by using the following method defaultEolFill() .
241
+ if style == self.SecundLevelTitle:
242
+ return QColor('#FFFF99')
243
+ elif style == self.Digits:
244
+ return QColor('#FFCC66')
245
+
246
+ return QsciLexerCustom.defaultPaper(self, style)
247
+
248
+ def defaultEolFill(self, style):
249
+ # This allowed to colorize all the background of a line.
250
+ if style == self.SecundLevelTitle:
251
+ return True
252
+ return QsciLexerCustom.defaultEolFill(self, style)
253
+
254
+ def styleText(self, start, end):
255
+ editor = self.editor()
256
+ if editor is None:
257
+ return
258
+
259
+ SCI = editor.SendScintilla
260
+ set_style = self.setStyling
261
+
262
+ source = ''
263
+ if end > editor.length():
264
+ end = editor.length()
265
+ if end > start:
266
+ data = bytearray(end - start + 1)
267
+ source = QString(data)
268
+ SCI(QsciScintilla.SCI_GETTEXTRANGE, start, end, source)
269
+ if not source:
270
+ return
271
+ self.startStyling(start, 0x1f)
272
+
273
+ index = SCI(QsciScintilla.SCI_LINEFROMPOSITION, start)
274
+
275
+ for line in source.splitlines(True):
276
+ # Try to uncomment the following line to see in the console
277
+ # how Scintiallla works. You have to think in terms of isolated
278
+ # lines rather than globally on the whole text.
279
+ # print line
280
+
281
+ length = len(line)
282
+
283
+ if line.startswith('+'):
284
+ newState = self.FirstLevelTitle
285
+ elif line.startswith('\t+') or line.startswith(' +'):
286
+ newState = self.SecundLevelTitle
287
+ else:
288
+ pos = SCI(QsciScintilla.SCI_GETLINEENDPOSITION, index) - length + 1
289
+ i = 0
290
+ while i < length:
291
+ wordLength = 1
292
+
293
+ self.startStyling(i + pos, 0x1f)
294
+
295
+ if chr(line[i]) in '0123456789':
296
+ #newState = self.Digits
297
+ pass
298
+ else:
299
+ newState = self.gett(line[i:])
300
+ wordLength = 5
301
+ if line[i:].startswith("class"):
302
+ newState = self.KeyWord2
303
+ wordLength = len('class')
304
+ elif line[i:].startswith('function'):
305
+ newState = self.KeyWord2
306
+ wordLength = len('function')
307
+ elif line[i:].startswith('null'):
308
+ newState = self.KeyWord2
309
+ wordLength = len('null')
310
+ else:
311
+ newState = self.Default
312
+
313
+
314
+ i += wordLength
315
+ set_style(wordLength, newState)
316
+ newState = None
317
+
318
+ if newState:
319
+ set_style(length, newState)
320
+
321
+ index += 1
322
+
323
+
324
+ if __name__ == "__main__":
325
+ app = QApplication(sys.argv)
326
+ win = MainWindow()
327
+ win.show()
328
+ sys.exit(app.exec_())