1
2
3
4 '''
5 Module to create a graphics window of default size 501x501 pixels (client drawing area)
6 using a coordinate system with x-axis from left to right, y-axis from bottom to top
7 (called user coordinates, default range 0..1, 0..1).
8
9 The module provides a global namespace for GPanel class methods. It also contaisn
10 the class GPane that can be used to embed a GPanel graphics window together with
11 other widgets in a GUI application.
12
13 The drawing methods perform drawing operation in an offscreen buffer (QPixmap)
14 and automatically renders it on the screen, so the graphics is shown step-by-step.
15
16 User coordinates: (ux, uy)
17 Pixel coordinates: (px, py) (screen pixels)
18 Transformation: px = px(ux), py = py(uy)
19 Pixel coordinate range: 0..winWidth - 1 (inclusive), 0..winHeight - 1 (inclusive); (0,0) upper left corner, x to the right, y downwards
20 User coordinate range: xmin..xmax (inclusive), ymin..ymax (inclusive); (0,0) lower left corner, x to the right, y upwards.
21
22 Transformation: user(ux, uy) to pixel(px, py):
23 (width = winWidth - 1, height = winHeight - 1)
24 px = a * ux + b
25 py = c * uy + d
26 with a = width / (xmax - xmin)
27 b = width * xmin / (xmin - xmax)
28 c = height / (ymin - ymax)
29 d = height * ymax / (ymax - ymin)
30
31 Inverse:
32 ux = (px - b) / a
33 uy = (py - d) / c
34
35 Because of the transformation from float to pixel coordinates, some rounding errors
36 may happen. If you need pixel accuracy, define a GPanel window with some user defined width x height,
37 e.g. makeGPanal(Size(501, 401)). Define then user coordinates in the range 0..width-1, 0..height-1, e.g.
38 window(0, 500, 0, 400). Now pixels in the range 0..500 x 0..400 (inclusive) may be addressed with no
39 rounding errors. (This is a total of 501 x 401 pixels.)
40
41 If you prefer a coordinate system with the origin at the upper left corner, define the y-range in reverse
42 order, e.g. window(0, 500, 400, 0).
43
44 WARNING: Because PyQt is not thread-safe, in principle all graphics drawings should be
45 executed in the GUI thread (for GPanel the main thread or a GUI callback).
46
47 In order to get notifications for keyboard and mouse callbacks, the main thread should
48 not be blocked otherwise than within the keep() function.
49
50 Typical program:
51
52 from pygpanel import *
53
54 makeGPanel(0, 10, 0, 10)
55 for ypt in range(0, 11, 1):
56 line(0, ypt, 10 - ypt, 0)
57 time.sleep(0.1) # to see what happens
58 keep()
59
60 keep() is blocking and keeps the graphics window open until the close button is hit or the
61 Python process terminates.
62 '''
63
64 from __future__ import division
65 from PyQt4 import QtGui, QtCore
66 from PyQt4.QtGui import *
67 from PyQt4.QtCore import *
68 import thread
69 import sys, time, math
70 import random
71
72 _p = None
73 isTigerJython = False
76
78 if _p == None:
79 raise _WindowNotInitialized("Use \"makeGPanel()\" to create the graphics window before calling GPanel methods.")
80
82 '''
83 Constructs a GPanel and displays a non-resizable graphics window.
84 Defaults with no parameter:
85 Window size: 501x501 pixels
86 Window title: "GPanel".
87 User coordinates: 0, 1, 0, 1.
88 Background color: white.
89 Pen color: black.
90 Pen size: 1.
91
92 1 Parameter: Size(window_width, window_height).
93 4 Parameters: xmin, xmax, ymin, ymax.
94
95 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
96 @param Size: a Size reference to define the dimension of the graphics windows.
97 @param xmin: left x user coordinate
98 @param xmax: right x user coordinate
99 @param ymin: lower y user coordinate
100 @param ymax: upper y user coordinate
101 @param kwargs: mousePressed, mouseReleased, mouseDragged, keyPressed, keyReleased, closed
102 '''
103 global _p
104
105 if _p == None:
106 _p = GPanel(*args)
107
108 for key in kwargs:
109 if key == "mousePressed":
110 _p.addMousePressListener(kwargs[key])
111 elif key == "mouseReleased":
112 _p.addMouseReleaseListener(kwargs[key])
113 elif key == "mouseDragged":
114 _p.addMouseDragListener(kwargs[key])
115 elif key == "keyPressed":
116 _p.addKeyPressListener(kwargs[key])
117 elif key == "keyReleased":
118 _p.addKeyReleaseListener(kwargs[key])
119 elif key == "closed":
120 _p.addCloseListener(kwargs[key])
121 return _p
122
124 '''
125 Registers the given function that is called when the title bar
126 close button is hit.
127
128 If a listener (!= None) is registered, the automatic closing is disabled.
129 To close the window, call sys.exit().
130
131 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
132 @param closeListener: a callback function called when the close button is hit
133 '''
134 _isGPanelValid()
135 _p.addCloseListener(closeListener)
136
138 '''
139 Registers a callback that is invoked when a key is pressed (and the graphics window has the focus).
140
141 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
142 @param onKeyPressed: a callback function called when a key is pressed
143 '''
144 _isGPanelValid()
145 _p.addKeyPressListener(onKeyPressed)
146
148 '''
149 Registers a callback that is invoked when a key is released (and the graphics window has the focus).
150
151 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
152 @param onKeyReleased: a callback function called when a key is pressed
153 '''
154 _isGPanelValid()
155 _p.addKeyReleaseListener(onKeyReleased)
156
158 '''
159 Registers a callback that is invoked when the mouse is moved while a mouse button is pressed (drag).
160
161 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
162 @param onMouseDragged: a callback function called when the moused is dragged
163 '''
164 _isGPanelValid()
165 _p.addMouseMoveListener(onMouseDragged)
166
168 '''
169 Registers a callback that is invoked when a mouse button is pressed.
170 Use isLeftMouseButton() or isRightMouseButton() to check which button used.
171
172 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
173 @param onMousePressed: a callback function called when a mouse button is pressed
174 '''
175 _isGPanelValid()
176 _p.addMousePressListener(onMousePressed)
177
179 '''
180 Registers a callback that is invoked when a mouse button is releases.
181 Use isLeftMouseButton() or isRightMouseButton() to check which button used.
182
183 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
184 @param onMouseReleased: a callback function called when a mouse button is released
185 '''
186 _isGPanelValid()
187 _p.addMouseReleaseListener(onMouseReleased)
188
189 -def arc(radius, startAngle, spanAngle):
190 '''
191 Draws a circle sector with center at the current graph cursor position,
192 given radius and given start and span angles.
193 @param radius: the radius of the arc
194 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise
195 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise
196 '''
197 _isGPanelValid()
198 _p.arc(radius, startAngle, spanAngle)
199
201 '''
202 Same as setBgColor().
203 '''
204 setBgColor(*args)
205
206 -def chord(radius, startAngle, spanAngle):
207 '''
208 Draws a circle chord with center at the current graph cursor position,
209 given radius and given start and span angles (in degrees, positive
210 counter-clockwise, zero to east).
211 @param radius: the radius of the arc
212 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise
213 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise
214 '''
215 _isGPanelValid()
216 _p.chord(radius, startAngle, spanAngle)
217
219 '''
220 Draws a circle with center at the current graph cursor position
221 with given radius in horizontal window coordinates.
222 @param radius: the radius of the circle
223 '''
224 _isGPanelValid()
225 _p.circle(radius)
226
228 '''
229 Clears the graphics window and the offscreen buffer used by the window
230 (fully paint with background color).
231 Sets the current graph cursor position to (0, 0).
232 If enableRepaint(false) only clears the offscreen buffer.
233 '''
234 _isGPanelValid()
235 _p.clear()
236
238 '''
239 Stop execution for given delay time.
240 @param delayTime: the delay time (in ms)
241 '''
242 time.sleep(delayTime / 1000.0)
243
245 '''
246 Draws a line form current graph cursor position to (x, y).
247 Sets the graph cursor position to (x, y).
248 Also with one parameter of type complex, list or tuple.
249 @param x: the x coordinate of the target point
250 @param y: the y coordinate of the target point
251 @param target: (alternative) the target point as complex, list or tuple
252 '''
253 x, y = _getCoords(*args)
254 _isGPanelValid()
255 _p.draw(x, y)
256
258 '''
259 Draws a coordinate system with annotated axes.
260 (You must increase the user coordinate system at least 10% in both directions.)
261
262 Overloaded variants:
263
264 drawGrid(x, y): Grid with 10 ticks in range 0..x, 0..y. Label text depends if x, y or int or float
265
266 drawGrid(x, y, color): same with given grid color
267
268 drawGrid(x1, x2, y1, y2): same with given span x1..x2, y1..y2
269
270 drawGrid(x1, x2, y1, y2, color): same with given grid color
271
272 drawGrid(x1, x2, y1, y2, x3, y3): same with given number of ticks x3, y3 in x- and y-direction
273 '''
274 _isGPanelValid()
275 _p.drawGrid(*args)
276
278 '''
279 Draws an ellipse with center at the current graph cursor position
280 with given axes.
281 @param a: the major ellipse axis
282 @param b: the minor ellipse axis
283 '''
284 _isGPanelValid()
285 _p.ellipse(a, b)
286
288 '''
289 Enables/Disables automatic repaint in graphics drawing methods.
290 @param enable: if True, the automatic repaint is enabled; otherwise disabled
291 '''
292 _isGPanelValid()
293 _p.enableRepaint(enable)
294
296 '''
297 Same as clear(), but lets the current graph cursor unganged.
298 '''
299 _isGPanelValid()
300 _p.erase()
301
302 -def fill(x, y, *args):
303 '''
304 Fills the closed unicolored region with the inner point (x, y) with
305 the replacement color (RGB, RGBA or X11 color string).
306 The old color is not given, the color of the current (x, y) pixel is taken.
307 @param x: the x coordinate of the inner point
308 @param y: the y coordinate of the inner point
309 @param color: the old color (RGB list/tuple or X11 color string) (may be omitted)
310 @param replacementColor: the new color (RGB list/tuple or X11 color string)
311 '''
312 _isGPanelValid()
313 _p.fill(x, y, *args)
314
315 -def fillArc(radius, startAngle, spanAngle):
316 '''
317 Draws a filled circle sector with center at the current graph cursor position,
318 given radius and given start and span angles (in degrees, positive
319 counter-clockwise, zero to east). (fill color = pen color)
320 @param radius: the radius of the arc
321 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise
322 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise
323 '''
324 _isGPanelValid()
325 _p.fillArc(radius, startAngle, spanAngle)
326
327 -def fillChord(radius, startAngle, spanAngle):
328 '''
329 Draws a filled circle chord with center at the current graph cursor position,
330 given radius and given start and span angles (in degrees, positive
331 counter-clockwise, zero to east). (fill color = pen color)
332 @param radius: the radius of the arc
333 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise
334 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise
335 '''
336 _isGPanelValid()
337 _p.fillChord(radius, startAngle, spanAngle)
338
340 '''
341 Draws a filled circle with center at the current graph cursor position
342 with given radius in horizontal window coordinates (fill color = pen color).
343 @param radius: the radius of the circle
344 '''
345 _isGPanelValid()
346 _p.fillCircle(radius)
347
349 '''
350 Draws a filled ellipse with center at the current graph cursor position
351 with given axes (fill color = pen color).
352 @param a: the major ellipse axis
353 @param b: the minor ellipse axis
354 '''
355 _isGPanelValid()
356 _p.fillEllipse(a, b)
357
359 '''
360 Closes the path started with startPath() and shows a filled polygon from the saved
361 draw() positions with given color.
362 '''
363 _isGPanelValid()
364 _p.fillPath(color)
365
367 '''
368 Draws a filled polygon with given list of vertexes (list of [x, y])
369 (fill color = pen color).
370 1 parameter: a list/tuple of the corners [x, y]
371 2 parameters: two lists/tuples x, y of corresponding x-y pairs
372 '''
373 _isGPanelValid()
374 _p.fillPolygon(*args)
375
377 '''
378 Draws a filled rectangle (fill color = pen color).
379 2 parameters: Center at the current graph cursor position
380 and given width and height
381 4 parameters: Given diagonal
382 '''
383 _isGPanelValid()
384 _p.fillRectangle(*args)
385
387 '''
388 Draws a filled triangle with given corners.
389 6 parameters: x1, y1, x2, y2, x3, y3 coordinates of corners
390 3 parameters: [x1, y1], [x2, y2], [x3, y3] lists of corners
391 '''
392 _isGPanelValid()
393 _p.fillTriangle(*args)
394
396 '''
397 Returns the tuple of user coordinates of the point on the line through the point pt1 = (x1, y1)
398 and the point pt2 = (x2, y2) that is in distance ratio times the length from pt1 to pt2 from
399 pt1. For ratio < 0 the point is in the opposite direction.
400 3 parameteters: pt1, pt2 (complex/list/tuple), ratio
401 5 parameteters: x1, y1, x2, y2, ratio
402 '''
403 if len(args) == 5:
404 x1 = args[0]
405 y1 = args[1]
406 x2 = args[2]
407 y2 = args[3]
408 ratio = args[4]
409 elif len(args) == 3:
410 x1, y1, x2, y2 = _get2Coords(args[0], args[1])
411 ratio = args[2]
412 else:
413 raise ValueError("Illegal number of parameters.")
414 _isGPanelValid()
415 return _p.getDividingPoint(x1, y1, x2, y2, ratio)
416
418 '''
419 Returns the QImage of the complete graphics area.
420 (For compatiblity with TigerJython.)
421 '''
422 _isGPanelValid()
423 return _p.getFullImage()
424
426 '''
427 Returns the QImage of the complete graphics area.
428 '''
429 _isGPanelValid()
430 return _p.getFullImage()
431
433 '''
434 Same as loadImage(filename)
435 (For compatiblity with TigerJython.)
436 '''
437 return loadImage(filename)
438
440 '''
441 Returns a QImage of the picture loaded from the given file. For pic_format = None,
442 the picture format is guessed from the file data.
443 @param: the file path to the picture file
444 @param pic_format: format of picture, supported: "None" (default), "GIF", "JPG",
445 "BMP", "PNG", "PBM", "PGM", "PPM", "TIFF", "XBM" "XPM".
446 '''
447 return GPanel.loadImage(filename, pic_format)
448
450 '''
451 Returns the QPainter reference used to draw into the offscreen buffer.
452 '''
453 _isGPanelValid()
454 return _p.getPainter()
455
457 '''
458 Returns the RGBA color tuple of a pixel with given user coordinates.
459 No params: Returns color at current graph cursor position.
460 '''
461 _isGPanelValid()
462 return _p.getPixelColor(*args)
463
465 '''
466 Returns the X11 color string of a pixel with given user coordinates.
467 No params: Returns color at current graph cursor position.
468 '''
469 _isGPanelValid()
470 return _p.getPixelColorStr(*args)
471
473 '''
474 Returns a tuple with current graph cursor position (tuple, user coordinates).
475 '''
476 _isGPanelValid()
477 return _p.getPos()
478
480 '''
481 Returns the current graph cursor x-position (user coordinates).
482 @return: x coordinate of graph cursor
483 @rtype: float
484 '''
485 _isGPanelValid()
486 return _p.getPosX()
487
489 '''
490 Returns the current graph cursor y-position (user coordinates).
491 @return: y coordinate of graph cursor
492 @rtype: float
493 '''
494 _isGPanelValid()
495 return _p.getPosY()
496
498 '''
499 Returns the width of the screen (in pixels).
500 @return: screen width
501 @rtype: int
502 '''
503 return GPanel.getScreenWidth()
504
506 '''
507 Returns the height of the screen (in pixels).
508 @return: screen height
509 @rtype: int
510 '''
511 return GPanel.getScreenHeight()
512
514 '''
515 Draws the picture with given string data in JPEG format at user coordinates of lower left corner.
516 @param data: picture data stream in string format
517 @param pic_format: format of picture, supported: "GIF", "JPG", "BMP", "PNG",
518 "PBM", "PGM", "PPM", "TIFF", "XBM" "XPM"
519 @param x: x coordinate of lower left corner
520 @param y: y coordinate of lower left corner
521 @return: True, if operation is successful; otherwise false
522 @rtype: boolean
523 '''
524 _isGPanelValid()
525 img = QImage()
526 rc = img.loadFromData(data, pic_format)
527 if rc:
528 image(img, x, y)
529 return True
530 return False
531
533 '''
534 Draws the picture with given file path or given image at given upper-left coordinates.
535 1st parameter: image path (string) or QImage reference
536 2nd, 3rd parameters: llx, lly (lower left corner in user coordinates)
537 '''
538 _isGPanelValid()
539 _p.showImage(*args)
540
547
554
556 '''
557 Blocks until the title bar's close button is hit. Then cleans up
558 the graphics system.
559 '''
560 _isGPanelValid()
561 _p.keep()
562
564 '''
565 Draws a line with given user start and end coordinates
566 and sets the graph cursor position to the end point.
567 Also with 2 parameters of type complex, list or tuple.
568 4 parameters: x1, y1, x2, y2
569 2 parameters: pt1, pt2 as complex/list/tuple
570 '''
571 x1, y1, x2, y2 = _get2Coords(*args)
572 _isGPanelValid()
573 _p.line(x1, y1, x2, y2)
574
576 '''
577 Sets the current pen size (width) (>=1).
578 Returns the previouis pen size.
579
580 Same as setPenSize(). For TigerJython compatiblity.
581 @param width: the pen width (>=1)
582 '''
583 setPenSize(width)
584
586 '''
587 Returns the tuple (r, g, b). For compatibility with TigerJython.
588 '''
589 return (r, g, b)
590
592 '''
593 Sets the current graph cursor position to given user coordinates.
594 (without drawing anything).
595 Also with 1 parameter of type complex, list or tuple.
596
597 Same as pos().
598 @param x: the x coordinate of the target point
599 @param y: the y coordinate of the target point
600 @param target: (alternative) the target point as complex, list or tuple
601 '''
602 pos(*args)
603
605 '''
606 Draws a single point with current pen size and pen color at given user coordinates.
607 No params: draws a current graph cursor position
608 @param x: the x coordinate of the target point
609 @param y: the y coordinate of the target point
610 @param target: (alternative) the target point as complex, list or tuple
611 '''
612 _isGPanelValid()
613 _p.point(*args)
614
616 '''
617 Draws a line plot with given x,y data.
618 1 parameter: a list/tuple of subsequent data points [x, y]
619 2 parameters: two lists/tuples x, y of corresponding x-y pairs
620 The graph cursor position remains unchanged.
621 '''
622 _isGPanelValid()
623 _p.linePlot(*args)
624
626 '''
627 Sets the current graph cursor position to given user coordinates (x, y).
628 (without drawing anything).
629 Also with 1 parameter of type complex, list or tuple.
630
631 Same as move().
632 @param x: the x coordinate of the target point
633 @param y: the y coordinate of the target point
634 @param target: (alternative) the target point as complex, list or tuple
635 '''
636 x, y = _getCoords(*args)
637 _isGPanelValid()
638 _p.pos(x, y)
639
641 '''
642 Draws a filled polygon with given list of vertexes (list of [x, y])
643 (fill color = pen color).
644 1 parameter: a list/tuple of the corners [x, y]
645 2 parameters: two lists/tuples x, y of corresponding x-y pairs
646 '''
647 _isGPanelValid()
648 _p.polygon(*args)
649
651 '''
652 Draws a rectangle.
653 2 parameters: Center at the current graph cursor position
654 and given width and height.
655 4 parameters: Given diagonal
656 '''
657 _isGPanelValid()
658 _p.rectangle(*args)
659
661 '''
662 Renders the offscreen buffer in the graphics window.
663 '''
664 _isGPanelValid()
665 _p.repaint()
666
668 '''
669 Restores the saved graphics from the image buffer. Use saveGraphics()
670 to save it.
671
672 Same as restoreGraphics() (for TigerJython compatibility).
673 '''
674 restoreGraphics()
675
678 '''
679 Restores the saved graphics from the image buffer. Use saveGraphics()
680 to save it.
681 '''
682 _isGPanelValid()
683 _p.restoreGraphics()
684
686 '''
687 Saves the current graphics into a image buffer. Use restoreGraphics()
688 to restore it.
689 '''
690 _isGPanelValid()
691 _p.saveGraphics()
692
694 '''
695 Sets the background color. All drawings are erased and the current
696 graph cursor is set to (0, 0).
697 1 parameter: value considered as X11 color string
698 3 parameters: values considered as RGB (alpha = 255)
699 4 parameters: values considered as RGBA
700 '''
701 _isGPanelValid()
702 return _p.setBgColor(*args)
703
705 '''
706 Sets the current pen color.
707 1 parameter: - string value considered as X11 color string
708 - list considered as [r, b, g] or [r, g, b, a]
709 - tuple considered as (r, b, g) or (r, g, b, a)
710 3 parameters: values considered as RGB (alpha = 255)
711 4 parameters: values considered as RGBA
712
713 Same as setPenColor(). For TigerJython compatiblity.
714 '''
715 return setPenColor(*args)
716
718 '''
719 Resets the drawing mode to standard (overwriting).
720 '''
721 _isGPanelValid()
722 _p.setPaintMode()
723
725 '''
726 Sets the current pen color.
727 1 parameter: - string value considered as X11 color string
728 - list considered as [r, b, g] or [r, g, b, a]
729 - tuple considered as (r, b, g) or (r, g, b, a)
730 3 parameters: values considered as RGB (alpha = 255)
731 4 parameters: values considered as RGBA
732 '''
733 _isGPanelValid()
734 return _p.setPenColor(*args)
735
737 '''
738 Sets the current pen size (width) (>=1).
739 Returns the previouis pen size.
740 Same as lineWidth().
741 @param width: the pen width (>=1)
742 '''
743 _isGPanelValid()
744 return _p.setPenSize(size)
745
747 '''
748 Sets the title in the window title bar.
749 @param title: the title text
750 '''
751 _isGPanelValid()
752 return _p.setTitle(size)
753
755 '''
756 Sets user coordinate system left_x, right_x, bottom_y, top_y (inclusive).
757 Same as window().
758
759 @param xmin: the x coordinate (of a visible pixel) at left border
760 @param xmax: the x coordinate (of a visible pixel) at right border
761 @param ymin: the y coordinate (of a visible pixel) at bottom border
762 @param ymax: the y coordinate (of a visible pixel) at top border
763 '''
764 _isGPanelValid()
765 _p.setUserCoords(xmin, xmax, ymin, ymax)
766
768 '''
769 Sets the screen position to the center of the screen.
770 '''
771 _isGPanelValid()
772 _p.setWindowCenter()
773
775 '''
776 Sets the screen position of the graphics window.
777 @param ulx: the upper left corner's x-coordinate
778 @param ulx: the upper left corner's y-coordinate
779 '''
780 _isGPanelValid()
781 _p.setWindowPos(ulx, uly)
782
784 '''
785 Performs pixel color XOR operation with the existing background pixel.
786 Be aware that if the background is white, drawing with a white pen shows a black pixel.
787 (Parameter not used, for TigerJython compatibility)
788 '''
789 _isGPanelValid()
790 _p.setXORMode()
791
794 '''
795 Starts recording the path vertexes. The positions of subsequent draw() operations are saved.
796 The path is used to show a filled polygon when fillPath() is called.
797 '''
798 _isGPanelValid()
799 _p.startPath()
800
802 '''
803 Saves the current graphics into a image buffer. Use restoreGraphics()
804 to restore it.
805
806 Same as saveGraphics() (for TigerJython compatibility).
807 '''
808 saveGraphics()
809
811 '''
812 Draws a text at given position (user coordinates).
813 1 parameter: at current graph cursor position
814 2 parameters: target point (comolex/list/tuple), text
815 3 parameters: x, y, text
816 '''
817 _isGPanelValid()
818 _p.text(*args)
819
821 '''
822 Sets the title in the window title bar.
823 Same as setTitle(), for TigerJython compatibility.
824 @param title: the title text
825 '''
826 _isGPanelValid()
827 _p.setTitle(title)
828
830 '''
831 Returns pixel coordinates (tuple) of given user coordinates (tuple).
832 '''
833 _isGPanelValid()
834 return _p.toPixel(user)
835
837 '''
838 Returns pixel y-increment of given user y-increment (always positive).
839 '''
840 _isGPanelValid()
841 return p.toPixelHeight(userHeight)
842
844 '''
845 Returns pixel x-increment of given user x-increment (always positive).
846 '''
847 _isGPanelValid()
848 return _p.toPixelWidth(userWidth)
849
851 '''
852 Returns pixel x-coordinate of given user x-coordinate.
853 '''
854 _isGPanelValid()
855 return _p.toPixelX(userX)
856
858 '''
859 Returns pixel y-coordinate of given user y-coordinate.
860 '''
861 _isGPanelValid()
862 return _p.toPixelY(userY)
863
865 '''
866 Returns user coordinates (tuple) of given pixel coordinates (tuple).
867 '''
868 _isGPanelValid()
869 return _p.toUser(pixel)
870
872 '''
873 Returns user y-increment of given pixel y-increment (always positive).
874 '''
875 _isGPanelValid()
876 return _p.toUserHeight(pixelHeight)
877
879 '''
880 Returns user x-increment of given pixel x-increment (always positive).
881 '''
882 _isGPanelValid()
883 return _p.toUserWidth(pixelWidth)
884
886 '''
887 Returns user x-coordinate of given pixel x-coordinate.
888 '''
889 _isGPanelValid()
890 return _p.toUserX(pixelX)
891
893 '''
894 Returns user y-coordinate of given pixel y-coordinate.
895 '''
896 _isGPanelValid()
897 return _p.toUserY(pixelY)
898
900 '''
901 Draws a triangle with given corners.
902 6 parameters: x1, y1, x2, y2, x3, y3 coordinates of corners
903 3 parameters: [x1, y1], [x2, y2], [x3, y3] lists of corners
904 '''
905 _isGPanelValid()
906 _p.triangle(*args)
907
908 -def window(xmin, xmax, ymin, ymax):
909 '''
910 Sets user coordinate system left_x, right_x, bottom_y, top_y (inclusive).
911 Same as setUserCoords(). For TigerJython compatiblity.
912
913 @param xmin: the x coordinate (of a visible pixel) at left border
914 @param xmax: the x coordinate (of a visible pixel) at right border
915 @param ymin: the y coordinate (of a visible pixel) at bottom border
916 @param ymax: the y coordinate (of a visible pixel) at top border
917 '''
918 _isGPanelValid()
919 _p.setUserCoords(xmin, xmax, ymin, ymax)
920
922 '''
923 Sets the screen position (pixel coordinates of upper left corner).
924 '''
925 _isGPanelValid()
926 _p.windowPosition(ulx, uly)
927
929 '''
930 Sets the window to the center of the screen.
931 '''
932 _isGPanelValid()
933 _p.windowCenter()
934
936 if len(args) == 2:
937 return args[0], args[1]
938 elif len(args) == 1:
939 if type(args[0]) == complex:
940 return args[0].real, args[0].imag
941 elif type(args[0]) == list or type(args[0]) == tuple:
942 return args[0][0], args[0][1]
943 else:
944 raise ValueError("Illegal parameter type.")
945 else:
946 raise ValueError("Illegal number of parameters.")
947
949 if len(args) == 4:
950 return args[0], args[1], args[2], args[3]
951 elif len(args) == 2:
952 val = []
953 for arg in args:
954 if type(arg) == complex:
955 val.append(arg.real)
956 val.append(arg.imag)
957 elif type(args) == list or type(args) == tuple:
958 val.append(arg[0])
959 val.append(arg[1])
960 else:
961 raise ValueError("Illegal parameter type.")
962 return val[0], val[1], val[2], val[3]
963 else:
964 raise ValueError("Illegal number of parameters.")
965
969 '''
970 Calls f() in a new thread.
971 '''
972 thread.start_new_thread(f, ())
973
980
983 '''
984 Returns a and b in y = a*x + b for given list X of x values and
985 corresponding list Y of values.
986 '''
987 def mean(Xs):
988 return sum(Xs) / len(Xs)
989 m_X = mean(X)
990 m_Y = mean(Y)
991
992 def std(Xs, m):
993 normalizer = len(Xs) - 1
994 return math.sqrt(sum((pow(x - m, 2) for x in Xs)) / normalizer)
995
996 def pearson_r(Xs, Ys):
997 sum_xy = 0
998 sum_sq_v_x = 0
999 sum_sq_v_y = 0
1000
1001 for (x, y) in zip(Xs, Ys):
1002 var_x = x - m_X
1003 var_y = y - m_Y
1004 sum_xy += var_x * var_y
1005 sum_sq_v_x += pow(var_x, 2)
1006 sum_sq_v_y += pow(var_y, 2)
1007 return sum_xy / math.sqrt(sum_sq_v_x * sum_sq_v_y)
1008
1009 r = pearson_r(X, Y)
1010 b = r * (std(Y, m_Y) / std(X, m_X))
1011 A = m_Y - b * m_X
1012 return b, A
1013
1014
1015
1016
1017
1018 -class Size():
1019 '''
1020 Class that defines the pair width, height of dimension attributes.
1021 '''
1023 self.width = width
1024 self.height = height
1025
1026
1027
1028
1029
1030
1031 -class GPanel(QtGui.QWidget):
1032 '''
1033 Class to create a graphics window of default size 501x501 pixels (client drawing area)
1034 using a coordinate system with x-axis from left to right, y-axis from bottom to top
1035 (called user coordinates, default range 0..1, 0..1).
1036
1037 The drawing methods perform drawing operation in an offscreen buffer (QPixmap)
1038 and automatically renders it on the screen, so the graphics is shown step-by-step.
1039
1040
1041 The drawing methods perform drawing operation in an offscreen buffer (pixmap)
1042 and automatically renders it on the screen, so the graphics is shown step-by-step.
1043
1044 User coordinates: (ux, uy)
1045 Pixel coordinates: (px, py) (screen pixels)
1046 Transformation: px = px(ux), py = py(uy)
1047 Pixel coordinate range: 0..winWidth - 1 (inclusive), 0..winHeight - 1 (inclusive); (0,0) upper left corner, x to the right, y downwards
1048 User coordinate range: xmin..xmax (inclusive), ymin..ymax (inclusive); (0,0) lower left corner, x to the right, y upwards.
1049
1050 Transformation: user(ux, uy) to pixel(px, py):
1051 (width = winWidth - 1, height = winHeight - 1)
1052 px = a * ux + b
1053 py = c * uy + d
1054 with a = width / (xmax - xmin)
1055 b = width * xmin / (xmin - xmax)
1056 c = height / (ymin - ymax)
1057 d = height * ymax / (ymax - ymin)
1058
1059 Inverse:
1060 ux = (px - b) / a
1061 uy = (py - d) / c
1062
1063 Because of the transformation from float to pixel coordinates, some rounding errors
1064 may happen. If you need pixel accuracy, define a GPanel window with some user defined width x height,
1065 e.g. GPanal(Size(501, 401)). Define then user coordinates in the range 0..width-1, 0..height-1, e.g.
1066 setUserCoords(0, 500, 0, 400). Now pixels in the range 0..500 x 0..400 (inclusive) may be addressed with no
1067 rounding errors. (This is a total of 501 x 401 pixels.)
1068
1069 If you prefer a coordinate system with the origin at the upper left corner, define the y-range in reverse
1070 order, e.g. setUserCoords(0, 500, 400, 0).
1071
1072 WARNING: Because PyQt is not thread-safe, in principle all graphics drawings should be
1073 executed in the GUI thread (for GPanel the main thread or a GUI callback).
1074
1075 Typical program:
1076
1077 from pygpanel import *
1078
1079 p = GPanel(0, 10, 0, 10)
1080 for ypt in range(0, 11, 1):
1081 p.line(0, ypt, 10 - ypt, 0)
1082 time.sleep(0.1) # to see what happens
1083 p.keep()
1084
1085 keep() is blocking and keeps the graphics panel open until the close button is hit or the
1086 Python process terminates.
1087 '''
1088
1090 '''
1091 Constructs a GPanel and displays a non-resizable graphics window.
1092 Defaults with no parameter:
1093 Window size: 501x501 pixels
1094 Window title: "GPanel"
1095 User coordinates: 0, 1, 0, 1
1096 Background color: white
1097 Pen color: black
1098 Pen size: 1
1099
1100 1 Parameter: Size(window_width, window_height)
1101 4 Parameters: xmin, xmax, ymin, ymax
1102 @param Size: a Size refererence that defines the width and height of the graphics window.
1103 '''
1104 try:
1105 self._embedded = kwargs['embedded']
1106 except:
1107 self._embedded = False
1108 else:
1109 if type(self._embedded) != bool:
1110 self._embedded = False
1111 if not self._embedded:
1112 self._app = QtGui.QApplication(sys.argv)
1113 super(GPanel, self).__init__()
1114 self.xmin = 0
1115 self.xmax = 1
1116 self.ymin = 0
1117 self.ymax = 1
1118 self.winWidth = 501
1119 self.winHeight = 501
1120 if not (len(args) == 0 or len(args) == 1 or len(args) == 4):
1121 raise ValueError("Illegal parameter list")
1122 if len(args) == 1:
1123 self.winWidth = args[0].width
1124 self.winHeight = args[0].height
1125 elif len(args) == 4:
1126 self.xmin = args[0]
1127 self.xmax = args[1]
1128 self.xmax = args[1]
1129 self.ymin = args[2]
1130 self.ymax = args[3]
1131 self._initUI()
1132
1134 self._setDefaults()
1135 self._label = QLabel()
1136 self._pixmap = QPixmap(QSize(self.winWidth, self.winHeight))
1137 self._vbox = QVBoxLayout()
1138 self._vbox.setContentsMargins(1, 1, 1, 1)
1139 self.setLayout(self._vbox)
1140 self._painter = QPainter(self._pixmap)
1141 self.paintEvent(0)
1142 self.clear()
1143 if not self._embedded:
1144 self.show()
1145 self.setFixedSize(self.winWidth + 2, self.winHeight + 2)
1146
1148 self.setWindowTitle('GPanel')
1149 self._penSize = 1
1150 self._penColor = QColor(0, 0, 0)
1151 self._bgColor = QColor(255, 255, 255, 255)
1152
1153
1154 if not self._embedded:
1155 ulx = 10
1156 uly = 10
1157 super(GPanel, self).move(ulx, uly)
1158
1159 self._xCurrent = 0
1160 self._yCurrent = 0
1161 self._enableRepaint = True
1162 self._adjust()
1163 self._onMousePressed = None
1164 self._onMouseReleased = None
1165 self._onMouseDragged = None
1166 self._onKeyPressed = None
1167 self._onKeyReleased = None
1168 self._isLeftMouseButton = False
1169 self._isRightMouseButton = False
1170 self._inMouseMoveCallback = False
1171 self._closeListener = None
1172 self._pathHistory = None
1173 self._savePixmap = None
1174 self._doRepaint = False
1175
1177 '''
1178 Clears the graphics window and the offscreen buffer used by the window
1179 (fully paint with background color).
1180 Sets the current graph cursor position to (0, 0).
1181 If enableRepaint(false) only clears the offscreen buffer.
1182 '''
1183 self._painter.setPen(QPen(self._bgColor, 1))
1184 self._painter.fillRect(QRect(0, 0, self.winWidth, self.winHeight), self._bgColor)
1185 self._painter.setPen(QPen(self._penColor, self._penSize))
1186 self._xCurrent = 0
1187 self._yCurrent = 0
1188 if self._enableRepaint:
1189 self.repaint()
1190
1192 '''
1193 Same as clear(), but lets the current graph cursor unganged.
1194 '''
1195 self._painter.setPen(QPen(self._bgColor, 1))
1196 self._painter.fillRect(QRect(0, 0, self.winWidth, self.winHeight), self._bgColor)
1197 self._painter.setPen(QPen(self._penColor, self._penSize))
1198 if self._enableRepaint:
1199 self.repaint()
1200
1202 '''
1203 Blocks until the title bar's close button is hit. Then cleans up
1204 the graphics system.
1205 '''
1206 self._app.exec_()
1207
1208
1209
1211 '''
1212 Sets the title in the window title bar.
1213 @param title: the title text
1214 '''
1215 self.setWindowTitle(title)
1216
1217
1219 if self._doRepaint:
1220 self._label.setPixmap(self._pixmap)
1221 self._vbox.addWidget(self._label)
1222 self._doRepaint = False
1223
1225 '''
1226 Same as setPenColor()
1227 '''
1228 self.setPenColor(*args)
1229
1230
1232 if len(args) == 1:
1233 if type(args[0]) == str:
1234 try:
1235 color = args[0].lower()
1236 rgb = x11ColorDict[color]
1237 except KeyError:
1238 raise ValueError("X11 color", args[0], "not found")
1239 r = rgb[0]
1240 g = rgb[1]
1241 b = rgb[2]
1242 a = 255
1243 elif type(args[0]) == list or type(args[0]) == tuple:
1244 if len(args[0]) == 3:
1245 r = args[0][0]
1246 g = args[0][1]
1247 b = args[0][2]
1248 a = 255
1249 elif len(args[0]) == 4:
1250 r = args[0][0]
1251 g = args[0][1]
1252 b = args[0][2]
1253 a = args[0][3]
1254 else:
1255 raise ValueError("Illegal parameter list")
1256 else:
1257 raise ValueError("Illegal parameter list")
1258
1259 elif len(args) == 3:
1260 r = args[0]
1261 g = args[1]
1262 b = args[2]
1263 a = 255
1264
1265 elif len(args) == 4:
1266 r = args[0]
1267 g = args[1]
1268 b = args[2]
1269 a = 255
1270
1271 else:
1272 raise ValueError("Illegal number of arguments")
1273
1274 return r, g, b, a
1275
1277 '''
1278 Sets the current pen color.
1279 1 parameter: - string value considered as X11 color string
1280 - list considered as [r, b, g] or [r, g, b, a]
1281 - tuple considered as (r, b, g) or (r, g, b, a)
1282 3 parameters: values considered as RGB (alpha = 255)
1283 4 parameters: values considered as RGBA
1284 '''
1285 r, g, b, a = self._toRGBA(*args)
1286 self._penColor = QColor(r, g, b, a)
1287 self._painter.setPen(QPen(self._penColor, self._penSize))
1288
1290 '''
1291 Sets the current pen size (width) (>=1).
1292 Returns the previous pen size.
1293 @param width: the pen width >=1)
1294 '''
1295 oldPenSize = self._penSize
1296 self._penSize = size
1297 self._painter.setPen(QPen(self._penColor, self._penSize))
1298 return oldPenSize
1299
1300
1302 '''
1303 Returns pixel coordinates (tuple) of given user coordinates (tupel).
1304 '''
1305 return self.toPixelX(user[0]), self.toPixelY(user[1])
1306
1308 '''
1309 Returns pixel x-coordinate of given user x-coordinate.
1310 '''
1311 return (int)(self._a * userX + self._b)
1312
1314 '''
1315 Returns pixel y-coordinate of given user y-coordinate.
1316 '''
1317 return (int)(self._c * userY + self._d)
1318
1320 '''
1321 Returns pixel x-increment of given user x-increment (always positive).
1322 '''
1323 return int(abs(self._a * userWidth))
1324
1326 '''
1327 Returns pixel y-increment of given user y-increment (always positive).
1328 '''
1329 return int(abs(self._c * userHeight))
1330
1332 '''
1333 Returns user coordinates (tuple) of given pixel coordinates (tuple).
1334 '''
1335 return self.toUserX(pixel[0]), self.toUserY(pixel[1])
1336
1338 '''
1339 Returns user x-coordinate of given pixel x-coordinate.
1340 '''
1341 a = (self.winWidth - 1) / (self.xmax - self.xmin)
1342 b = (self.winWidth - 1) * self.xmin / (self.xmin - self.xmax)
1343 return (pixelX - b) / a
1344
1346 '''
1347 Returns user y-coordinate of given pixel y-coordinate.
1348 '''
1349 c = (self.winHeight - 1) / (self.ymin - self.ymax)
1350 d = (self.winHeight - 1) * self.ymax / (self.ymax - self.ymin)
1351 return (pixelY - d) / c
1352
1354 '''
1355 Returns user x-increment of given pixel x-increment (always positive).
1356 '''
1357 a = (self.winWidth - 1) / (self.xmax - self.xmin)
1358 return abs(pixelWidth / a)
1359
1361 '''
1362 Returns user y-increment of given pixel y-increment (always positive).
1363 '''
1364 c = (self.winWidth - 1) / (self._ymin - self._ymax)
1365 return abs(pixelHeight / c)
1366
1368 '''
1369 Sets user coordinate system left_x, right_x, bottom_y, top_y (inclusive).
1370 @param xmin: the x coordinate (of a visible pixel) at left border
1371 @param xmax: the x coordinate (of a visible pixel) at right border
1372 @param ymin: the y coordinate (of a visible pixel) at bottom border
1373 @param ymax: the y coordinate (of a visible pixel) at top border
1374 '''
1375 self.xmin = xmin
1376 self.xmax = xmax
1377 self.ymin = ymin
1378 self.ymax = ymax
1379 self._adjust()
1380
1382 self._a = (self.winWidth - 1) / (self.xmax - self.xmin)
1383 self._b = (self.winWidth - 1) * self.xmin / (self.xmin - self.xmax)
1384 self._c = (self.winHeight - 1) / (self.ymin - self.ymax)
1385 self._d = (self.winHeight - 1) * self.ymax / (self.ymax - self.ymin)
1386
1387
1388
1390 '''
1391 Renders the offscreen buffer in the graphics window.
1392 '''
1393 self._doRepaint = True
1394 self.update()
1395 QApplication.processEvents()
1396
1398 '''
1399 Enables/Disables automatic repaint in graphics drawing methods.
1400 @param enable: if True, the automatic repaint is enabled; otherwise disabled
1401 '''
1402 self._enableRepaint = enable
1403
1404 - def line(self, x1, y1, x2, y2):
1405 '''
1406 Draws a line with given user start and end coordinates
1407 and sets the graph cursor position to the end point.
1408 Also with 2 parameters of type complex, list or tuple.
1409 4 parameters: x1, y1, x2, y2
1410 2 parameters: pt1, pt2 as complex/list/tuple
1411 '''
1412 xStart = self.toPixelX(x1)
1413 yStart = self.toPixelY(y1)
1414 xEnd = self.toPixelX(x2)
1415 yEnd = self.toPixelY(y2)
1416 self._painter.drawLine(xStart, yStart, xEnd, yEnd)
1417 self._xCurrent = x2
1418 self._yCurrent = y2
1419 if self._enableRepaint:
1420 self.repaint()
1421
1422 - def pos(self, x, y):
1423 '''
1424 Sets the current graph cursor position to given user coordinates.
1425 (without drawing anything, same as move()).
1426 @param x: the x coordinate of the target point
1427 @param y: the y coordinate of the target point
1428 @param target: (alternative) the target point as complex, list or tuple
1429 '''
1430 self._xCurrent = x
1431 self._yCurrent = y
1432
1433 - def move(self, x, y):
1434
1435 '''
1436 Sets the current graph cursor position to given user coordinates.
1437 (without drawing anything, same as pos()).
1438 @param x: the x coordinate of the target point
1439 @param y: the y coordinate of the target point
1440 @param target: (alternative) the target point as complex, list or tuple
1441 '''
1442 self.pos(x, y)
1443
1444 - def draw(self, x, y):
1445 '''
1446 Draws a line form current graph cursor position to (x, y).
1447 Sets the graph cursor position to (x, y).
1448 @param x: the x coordinate of the target point
1449 @param y: the y coordinate of the target point
1450 @param target: (alternative) the target point as complex, list or tuple
1451 '''
1452 self.line(self._xCurrent, self._yCurrent, x, y)
1453 if self._pathHistory != None:
1454 self._pathHistory.append([x, y])
1455
1457 '''
1458 Draws a line plot with given x,y data.
1459 1 parameter: a list/tuple of subsequent data points [x, y]
1460 2 parameters: two lists/tuples x, y of corresponding x-y pairs
1461 The graph cursor position remains unchanged.
1462 '''
1463 nodes = []
1464 if len(args) == 1:
1465 for pt in args[0]:
1466 node = [pt[0], pt[1]]
1467 nodes.append(node)
1468 elif len(args) == 2:
1469 if len(args[0]) != len(args[1]):
1470 raise ValueError("x and y list/tuple must have equal size")
1471 for i in range(len(args[0])):
1472 node = [args[0][i], args[1][i]]
1473 nodes.append(node)
1474 else:
1475 raise ValueError("Illegal number of parameters.")
1476
1477 for i in range(len(nodes) - 1):
1478 x1 = self.toPixelX(nodes[i][0])
1479 y1 = self.toPixelY(nodes[i][1])
1480 x2 = self.toPixelX(nodes[i + 1][0])
1481 y2 = self.toPixelY(nodes[i + 1][1])
1482 self._painter.drawLine(x1, y1, x2, y2)
1483
1484 if self._enableRepaint:
1485 self.repaint()
1486
1488 '''
1489 Returns a tuple with current graph cursor position (tuple, user coordinates).
1490 '''
1491 return self._xCurrent, self._yCurrent
1492
1494 '''
1495 Returns the current graph cursor x-position (user coordinates).
1496 '''
1497 return self._xCurrent
1498
1500 '''
1501 Returns the current graph cursor y-position (user coordinates).
1502 '''
1503 return self._yCurrent
1504
1505 - def text(self, *args):
1506 '''
1507 Draws a text at given position (user coordinates).
1508 1 parameter: at current graph cursor position
1509 2 parameters: target point (comolex/list/tuple), text
1510 3 parameters: x, y, text
1511 '''
1512 if len(args) == 1:
1513 xPos = self.toPixelX(self._xCurrent)
1514 yPos = self.toPixelY(self._yCurrent)
1515 text = args[0]
1516 elif len(args) == 2:
1517 xPos, yPos = _getCoords(args[0][:-1])
1518 text = args[1]
1519 elif len(args) == 3:
1520 xPos = self.toPixelX(args[0])
1521 yPos = self.toPixelY(args[1])
1522 text = args[2]
1523 else:
1524 raise ValueError("Illegal number of arguments")
1525
1526 self._painter.drawText(xPos, yPos, text)
1527 if self._enableRepaint:
1528 self.repaint()
1529
1531 '''
1532 Registers the given function that is called when the title bar
1533 close button is hit. If a listener (!= None) is registered,
1534 the automatic closing is disabled. To close the window, call
1535 sys.exit().
1536
1537 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
1538 @param closeListener: a callback function called when the close button is hit
1539 '''
1540 self._closeListener = closeListener
1541
1543
1544 if self._closeListener != None:
1545 e.ignore()
1546 self._closeListener()
1547
1549 '''
1550 Sets the background color. All drawings are erased and the current
1551 graph cursor is set to (0, 0).
1552
1553 1 parameter: - string value considered as X11 color string
1554 - list considered as [r, b, g] or [r, g, b, a]
1555 - tuple considered as (r, b, g) or (r, g, b, a)
1556 3 parameters: values considered as RGB (alpha = 255)
1557 4 parameters: values considered as RGBA
1558 '''
1559 r, g, b, a = self._toRGBA(*args)
1560 self._bgColor = QColor(r, g, b, a)
1561 self.clear()
1562
1563
1565 '''
1566 Draws a circle with center at the current graph cursor position
1567 with given radius in horizontal window coordinates.
1568 @param radius: the radius of the circle
1569 '''
1570 xPix = self.toPixelX(self._xCurrent)
1571 yPix = self.toPixelY(self._yCurrent)
1572 rPix = self.toPixelWidth(radius)
1573 self._painter.drawEllipse(QPointF(xPix, yPix), rPix, rPix)
1574 if self._enableRepaint:
1575 self.repaint()
1576
1578 '''
1579 Draws a filled circle with center at the current graph cursor position
1580 with given radius in horizontal window coordinates (fill color = pen color).
1581 @param radius: the radius of the circle
1582 '''
1583 xPix = self.toPixelX(self._xCurrent)
1584 yPix = self.toPixelY(self._yCurrent)
1585 rPix = self.toPixelWidth(radius)
1586 self._painter.setPen(Qt.NoPen)
1587 self._painter.setBrush(QBrush(self._penColor))
1588 self._painter.drawEllipse(QPointF(xPix, yPix), rPix, rPix)
1589 if self._enableRepaint:
1590 self.repaint()
1591 self._painter.setPen(QPen(self._penColor, self._penSize))
1592 self._painter.setBrush(Qt.NoBrush)
1593
1594
1596 '''
1597 Draws an ellipse with center at the current graph cursor position
1598 with given axes.
1599 @param a: the major ellipse axis
1600 @param b: the minor ellipse axis
1601 '''
1602 xPix = self.toPixelX(self._xCurrent)
1603 yPix = self.toPixelY(self._yCurrent)
1604 aPix = self.toPixelWidth(a)
1605 bPix = self.toPixelHeight(b)
1606 self._painter.drawEllipse(QPointF(xPix, yPix), aPix, bPix)
1607 if self._enableRepaint:
1608 self.repaint()
1609
1611 '''
1612 Draws a filled ellipse with center at the current graph cursor position
1613 with given axes (fill color = pen color).
1614 @param a: the major ellipse axis
1615 @param b: the minor ellipse axis
1616 '''
1617 xPix = self.toPixelX(self._xCurrent)
1618 yPix = self.toPixelY(self._yCurrent)
1619 aPix = self.toPixelWidth(a)
1620 bPix = self.toPixelHeight(b)
1621 self._painter.setPen(Qt.NoPen)
1622 self._painter.setBrush(QBrush(self._penColor))
1623 self._painter.drawEllipse(QPointF(xPix, yPix), aPix, bPix)
1624 if self._enableRepaint:
1625 self.repaint()
1626 self._painter.setPen(QPen(self._penColor, self._penSize))
1627 self._painter.setBrush(Qt.NoBrush)
1628
1630 '''
1631 Draws a rectangle.
1632 2 parameters: Center at the current graph cursor position
1633 and given width and height.
1634 4 parameters: Given diagonal
1635 '''
1636 if len(args) == 2:
1637 wPix = self.toPixelWidth(args[0])
1638 hPix = self.toPixelHeight(args[1])
1639 ulx = self.toPixelX(self._xCurrent) - wPix // 2
1640 uly = self.toPixelY(self._yCurrent) - hPix // 2
1641 elif len(args) == 4:
1642 wPix = self.toPixelWidth(args[2] - args[0])
1643 hPix = self.toPixelHeight(args[3] - args[1])
1644 ulx = self.toPixelX(args[0])
1645 uly = self.toPixelY(args[1])
1646 self._painter.drawRect(ulx, uly, wPix, hPix)
1647 if self._enableRepaint:
1648 self.repaint()
1649
1651 '''
1652 Draws a filled rectangle (fill color = pen color).
1653 2 parameters: Center at the current graph cursor position
1654 and given width and height.
1655 4 parameters: Given diagonal
1656 '''
1657 if len(args) == 2:
1658 wPix = self.toPixelWidth(args[0])
1659 hPix = self.toPixelHeight(args[1])
1660 ulx = self.toPixelX(self._xCurrent) - wPix // 2
1661 uly = self.toPixelY(self._yCurrent) - hPix // 2
1662 elif len(args) == 4:
1663 wPix = self.toPixelWidth(args[2] - args[0])
1664 hPix = self.toPixelHeight(args[3] - args[1])
1665 ulx = self.toPixelX(args[0])
1666 uly = self.toPixelY(args[1])
1667 self._painter.setPen(Qt.NoPen)
1668 self._painter.setBrush(QBrush(self._penColor))
1669 self._painter.drawRect(ulx, uly, wPix, hPix)
1670 if self._enableRepaint:
1671 self.repaint()
1672 self._painter.setPen(QPen(self._penColor, self._penSize))
1673 self._painter.setBrush(Qt.NoBrush)
1674
1676 '''
1677 Draws a polygon with given list of vertexes (list of [x, y] or (x, y))
1678 (fill color = pen color).
1679 1 parameter: a list/tuple of the corners [x, y] or (x, y)
1680 2 parameters: two lists/tuples x, y of corresponding x-y pairs
1681 '''
1682 nodes = []
1683 if len(args) == 1:
1684 for pt in args[0]:
1685 node = QPointF(self.toPixelX(pt[0]), self.toPixelY(pt[1]))
1686 nodes.append(node)
1687 elif len(args) == 2:
1688 if len(args[0]) != len(args[1]):
1689 raise ValueError("x and y list/tuple must have equal size")
1690 for i in range(len(args[0])):
1691 node = QPointF(self.toPixelX(args[0][i]), self.toPixelY(args[1][i]))
1692 nodes.append(node)
1693 else:
1694 raise ValueError("Illegal number of parameters.")
1695 p = QPolygonF(nodes)
1696 self._painter.drawPolygon(p)
1697 if self._enableRepaint:
1698 self.repaint()
1699
1701 '''
1702 Draws a filled polygon with given list of vertexes (list of [x, y] or (x, y))
1703 (fill color = pen color).
1704 1 parameter: a list/tuple of the corners [x, y] or (x, y)
1705 2 parameters: two lists/tuples x, y of corresponding x-y pairs
1706 '''
1707 nodes = []
1708 if len(args) == 1:
1709 for pt in args[0]:
1710 node = QPointF(self.toPixelX(pt[0]), self.toPixelY(pt[1]))
1711 nodes.append(node)
1712 elif len(args) == 2:
1713 if len(args[0]) != len(args[1]):
1714 raise ValueError("x and y list/tuple must have equal size")
1715 for i in range(len(args[0])):
1716 node = QPointF(self.toPixelX(args[0][i]), self.toPixelY(args[1][i]))
1717 nodes.append(node)
1718 else:
1719 raise ValueError("Illegal number of parameters.")
1720 p = QPolygonF(nodes)
1721 self._painter.setPen(Qt.NoPen)
1722 self._painter.setBrush(QBrush(self._penColor))
1723 self._painter.drawPolygon(p)
1724 if self._enableRepaint:
1725 self.repaint()
1726 self._painter.setPen(QPen(self._penColor, self._penSize))
1727 self._painter.setBrush(Qt.NoBrush)
1728
1730 '''
1731 Draws a triangle with given corners.
1732 6 parameters: x1, y1, x2, y2, x3, y3 coordinates of corners
1733 3 parameters: [x1, y1], [x2, y2], [x3, y3] lists of corners
1734 '''
1735 if len(args) == 6:
1736 corners = [[args[0], args[1]], [args[2], args[3]], [args[4], args[5]]]
1737 self.polygon(corners)
1738 elif len(args) == 3:
1739 corners = [args[0], args[1], args[2]]
1740 self.polygon(corners)
1741 else:
1742 raise ValueError("Illegal number of parameters.")
1743
1745 '''
1746 Draws a filled triangle with given corners.
1747 6 parameters: x1, y1, x2, y2, x3, y3 coordinates of corners
1748 3 parameters: [x1, y1], [x2, y2], [x3, y3] lists of corners
1749 '''
1750 if len(args) == 6:
1751 corners = [[args[0], args[1]], [args[2], args[3]], [args[4], args[5]]]
1752 self.fillPolygon(corners)
1753 elif len(args) == 3:
1754 corners = [args[0], args[1], args[2]]
1755 self.fillPolygon(corners)
1756 else:
1757 raise ValueError("Illegal number of parameters.")
1758
1759 - def arc(self, r, startAngle, spanAngle):
1760 '''
1761 Draws a circle sector with center at the current graph cursor position,
1762 given radius and given start and span angles.
1763 @param radius: the radius of the arc
1764 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise
1765 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise
1766 '''
1767 xPix = self.toPixelX(self._xCurrent)
1768 yPix = self.toPixelY(self._yCurrent)
1769 rPix = self.toPixelWidth(r)
1770 topLeft = QPoint(xPix - rPix, yPix - rPix)
1771 bottomRight = QPoint(xPix + rPix, yPix + rPix)
1772 rect = QRect(topLeft, bottomRight)
1773 self._painter.drawArc(rect, int(16 * startAngle), int(16 * spanAngle))
1774 if self._enableRepaint:
1775 self.repaint()
1776
1777 - def fillArc(self, r, startAngle, spanAngle):
1778 '''
1779 Draws a filled circle sector with center at the current graph cursor position,
1780 given radius and given start and span angles.
1781 @param radius: the radius of the arc
1782 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise
1783 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise
1784 '''
1785 xPix = self.toPixelX(self._xCurrent)
1786 yPix = self.toPixelY(self._yCurrent)
1787 rPix = self.toPixelWidth(r)
1788 topLeft = QPoint(xPix - rPix, yPix - rPix)
1789 bottomRight = QPoint(xPix + rPix, yPix + rPix)
1790 rect = QRect(topLeft, bottomRight)
1791 self._painter.setPen(Qt.NoPen)
1792 self._painter.setBrush(QBrush(self._penColor))
1793 self._painter.drawChord(rect, int(16 * startAngle), int(16 * spanAngle))
1794
1795
1796 xStart = int(xPix + rPix * math.cos(math.radians(startAngle)))
1797 yStart = int(yPix - rPix * math.sin(math.radians(startAngle)))
1798 xEnd = int(xPix + rPix * math.cos(math.radians(startAngle + spanAngle)))
1799 yEnd = int(yPix - rPix * math.sin(math.radians(startAngle + spanAngle)))
1800 triangle = [[xPix, yPix], [xStart, yStart], [xEnd, yEnd]]
1801 nodes = []
1802 for pt in triangle:
1803 node = QPointF(pt[0], pt[1])
1804 nodes.append(node)
1805 p = QPolygonF(nodes)
1806 self._painter.drawPolygon(p)
1807
1808 if self._enableRepaint:
1809 self.repaint()
1810 self._painter.setPen(QPen(self._penColor, self._penSize))
1811 self._painter.setBrush(Qt.NoBrush)
1812
1813 - def chord(self, r, startAngle, spanAngle):
1814 '''
1815 Draws a circle chord with center at the current graph cursor position,
1816 given radius and given start and span angles (in degrees, positive
1817 counter-clockwise, zero to east).
1818 @param radius: the radius of the arc
1819 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise
1820 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise
1821 '''
1822 xPix = self.toPixelX(self._xCurrent)
1823 yPix = self.toPixelY(self._yCurrent)
1824 rPix = self.toPixelWidth(r)
1825 topLeft = QPoint(xPix - rPix, yPix - rPix)
1826 bottomRight = QPoint(xPix + rPix, yPix + rPix)
1827 rect = QRect(topLeft, bottomRight)
1828 self._painter.drawChord(rect, int(16 * startAngle), int(16 * spanAngle))
1829 if self._enableRepaint:
1830 self.repaint()
1831
1832 - def fillChord(self, r, startAngle, spanAngle):
1833 '''
1834 Draws a filled circle chord with center at the current graph cursor position,
1835 given radius and given start and span angles (in degrees, positive
1836 counter-clockwise, zero to east).
1837 @param radius: the radius of the arc
1838 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise
1839 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise
1840 '''
1841 xPix = self.toPixelX(self._xCurrent)
1842 yPix = self.toPixelY(self._yCurrent)
1843 rPix = self.toPixelWidth(r)
1844 topLeft = QPoint(xPix - rPix, yPix - rPix)
1845 bottomRight = QPoint(xPix + rPix, yPix + rPix)
1846 rect = QRect(topLeft, bottomRight)
1847 self._painter.setPen(Qt.NoPen)
1848 self._painter.setBrush(QBrush(self._penColor))
1849 self._painter.drawChord(rect, int(16 * startAngle), int(16 * spanAngle))
1850 if self._enableRepaint:
1851 self.repaint()
1852 self._painter.setPen(QPen(self._penColor, self._penSize))
1853 self._painter.setBrush(Qt.NoBrush)
1854
1856 '''
1857 Starts recording the path vertexes. The positions of subsequent draw() operations are saved.
1858 The path is used to show a filled polygon when fillPath() is called.
1859 '''
1860 self._pathHistory = [[self._xCurrent, self._yCurrent]]
1861
1863 '''
1864 Closes the path started with startPath() and shows a filled polygon from the saved
1865 draw() positions with given color.
1866 '''
1867 if self._pathHistory == None:
1868 raise Exception("Must call startPath() before fillPath()")
1869 oldColor = self._penColor
1870 oldSize = self._penSize
1871 self.setPenColor(color)
1872 self.setPenSize(1)
1873 self.fillPolygon(self._pathHistory)
1874 self._painter.setPen(QPen(oldColor, oldSize))
1875 self.polygon(self._pathHistory)
1876 self._pathHistory = None
1877
1879 '''
1880 Draws the picture with given file path or given image at given upper-left coordinates.
1881 1st parameter: image path (string) or QImage reference
1882 2nd, 3rd parameters: llx, lly (lower left corner in user coordinates)
1883 '''
1884 if type(args[0])== str:
1885 img = QImage(args[0])
1886 else:
1887 img = args[0]
1888 xPix = self.toPixelX(args[1])
1889 yPix = self.toPixelY(args[2]) - img.height() + 1
1890 self._painter.drawImage(xPix, yPix, img)
1891 if self._enableRepaint:
1892 self.repaint()
1893
1894 - def point(self, *args):
1895 '''
1896 Draws a single point with current pen size and pen color at given user coordinates.
1897 No params: draws a current graph cursor position
1898 @param x: the x coordinate of the target point
1899 @param y: the y coordinate of the target point
1900 @param target: (alternative) the target point as complex, list or tuple
1901 '''
1902 if len(args) == 0:
1903 xPix = self.toPixelX(self._xCurrent)
1904 yPix = self.toPixelY(self._yCurrent)
1905 elif len(args) == 1:
1906 pt = _getCoords(*args)
1907 xPix = self.toPixelX(pt[0])
1908 yPix = self.toPixelY(pt[1])
1909 elif len(args) == 2:
1910 xPix = self.toPixelX(args[0])
1911 yPix = self.toPixelY(args[1])
1912 else:
1913 raise ValueError("Illegal number of arguments")
1914 self._painter.drawPoint(QPointF(xPix, yPix))
1915 if self._enableRepaint:
1916 self.repaint()
1917
1919 '''
1920 Returns the RGBA color tuple of a pixel with given user coordinates.
1921 No params: Returns color at current graph cursor position.
1922 '''
1923 if len(args) == 0:
1924 xPix = self.toPixelX(self._xCurrent)
1925 yPix = self.toPixelY(self._yCurrent)
1926 elif len(args) == 2:
1927 xPix = self.toPixelX(args[0])
1928 yPix = self.toPixelY(args[1])
1929 else:
1930 raise ValueError("Illegal number of parameters.")
1931 img = self._pixmap.toImage()
1932 c = img.pixel(xPix, yPix)
1933 return QColor(c).getRgb()
1934
1936 '''
1937 Returns the X11 color string of a pixel with given user coordinates.
1938 No params: Returns color at current graph cursor position.
1939 '''
1940 r, g, b, a = self.getPixelColor(*args)
1941 for name, rgb in x11ColorDict.items():
1942 if name[-1] in [str(i) for i in range(10)]:
1943 continue
1944 if " " in name:
1945 continue
1946 if "grey" in name:
1947 continue
1948 if rgb == [r, g, b]:
1949 return name
1950 raise ValueError("X11 color", [r, g, b], "not found")
1951
1953 if type(color) == str:
1954 try:
1955 color = color.lower()
1956 color = x11ColorDict[color]
1957 return color
1958 except KeyError:
1959 raise ValueError("X11 color", color, "not found")
1960 else:
1961 return color
1962
1963 - def fill(self, x, y, *args):
1964 '''
1965 Fills the closed unicolored region with the inner point (x, y) with
1966 the replacement color (RGB, RGBA or X11 color string).
1967 The old color is not given, the color of the current (x, y) pixel is taken.
1968 @param x: the x coordinate of the inner point
1969 @param y: the y coordinate of the inner point
1970 @param color: the old color (RGB list/tuple or X11 color string) (may be omitted)
1971 @param replacementColor: the new color (RGB list/tuple or X11 color string)
1972 '''
1973 xPix = self.toPixelX(x)
1974 yPix = self.toPixelY(y)
1975
1976 if len(args) == 2:
1977 color = self._toColor(args[0])
1978 replacementColor = self._toColor(args[1])
1979 elif len(args) == 1:
1980 im = self._pixmap.toImage()
1981 col= QColor(im.pixel(xPix, yPix))
1982 color = [col.red(), col.green(), col.blue()]
1983 replacementColor = self._toColor(args[0])
1984 else:
1985 raise ValueError("Illegal number of parameters.")
1986
1987 img = GPanel.floodFill(self._pixmap, [self.toPixelX(x), self.toPixelY(y)], color, replacementColor)
1988 self._painter.drawImage(0, 0, img)
1989 if self._enableRepaint:
1990 self.repaint()
1991
1993 '''
1994 Returns the QPainter reference used to draw into the offscreen buffer.
1995 '''
1996 return self._painter
1997
1999 '''
2000 Returns the QImage reference of the whole graphics area.
2001 '''
2002 return self._pixmap.toImage()
2003
2005 '''
2006 Draws a coordinate system with annotated axes.
2007 (You must increase the user coordinate system at least 10% in both directions.)
2008 drawGrid(x, y): Grid with 10 ticks in range 0..x, 0..y. Label text depends if x, y or int or float
2009 drawGrid(x, y, color): same with given grid color
2010 drawGrid(x1, x2, y1, y2): same with given span x1..x2, y1..y2
2011 drawGrid(x1, x2, y1, y2, color): same with given grid color
2012 drawGrid(x1, x2, y1, y2, x3, y3): same with given number of ticks x3, y3 in x- and y-direction
2013 '''
2014 if len(args) == 2:
2015 self._drawGrid(0, args[0], 0, args[1], 10, 10, None)
2016 if len(args) == 3:
2017 self._drawGrid(0, args[0], 0, args[1], 10, 10, args[2])
2018 elif len(args) == 4:
2019 self._drawGrid(args[0], args[1], args[2], args[3], 10, 10, None)
2020 elif len(args) == 5:
2021 self._drawGrid(args[0], args[1], args[2], args[3], 10, 10, args[4])
2022 elif len(args) == 6:
2023 self._drawGrid(args[0], args[1], args[2], args[3], args[4], args[5], None)
2024 elif len(args) == 7:
2025 self._drawGrid(args[0], args[1], args[2], args[3], args[4], args[5], args[6])
2026 else:
2027 raise ValueError("Illegal number of parameters.")
2028
2029 - def _drawGrid(self, xmin, xmax, ymin, ymax, xticks, yticks, color):
2030
2031 xPos = self.getPosX()
2032 yPos = self.getPosY()
2033 if color != None:
2034 oldColor = self._penColor
2035 self.setPenColor(color)
2036
2037 for i in range(yticks + 1):
2038 y = ymin + (ymax - ymin) / float(yticks) * i
2039 self.line(xmin, y, xmax, y)
2040 if isinstance(ymin, float) or isinstance(ymax, float):
2041 self.text(xmin - 0.09 * (xmax - xmin), y, str(y))
2042 else:
2043 self.text(xmin - 0.09 * (xmax - xmin), y, str(int(y)))
2044
2045 for k in range(xticks + 1):
2046 x = xmin + (xmax - xmin) / float(xticks) * k
2047 self.line(x, ymin, x, ymax)
2048 if isinstance(xmin, float) or isinstance(xmax, float):
2049 self.text(x, ymin - 0.05 * (ymax - ymin), str(x))
2050 else:
2051 self.text(x, ymin - 0.05 * (ymax - ymin), str(int(x)))
2052
2053 self.pos(xPos, yPos)
2054 if color != None:
2055 self._penColor = oldColor
2056 self._painter.setPen(QPen(self._penColor, self._penSize))
2057
2059 '''
2060 Registers a callback that is invoked when a mouse button is pressed.
2061 Use isLeftMouseButton() or isRightMouseButton() to check which button used.
2062
2063 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
2064 @param onMousePressed: a callback function called when a mouse button is pressed
2065 '''
2066 self._onMousePressed = onMousePressed
2067
2069 '''
2070 Registers a callback that is invoked when a mouse button is releases.
2071 Use isLeftMouseButton() or isRightMouseButton() to check which button used.
2072
2073 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
2074 @param onMouseReleased: a callback function called when a mouse button is released
2075 '''
2076 self._onMouseReleased = onMouseReleased
2077
2079 '''
2080 Registers a callback that is invoked when the mouse is moved while a mouse button is pressed (drag).
2081
2082 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
2083 @param onMouseDragged: a callback function called when the moused is dragged
2084 '''
2085 self._onMouseDragged = onMouseDragged
2086
2092
2098
2100 '''
2101 Registers a callback that is invoked when a key is pressed (and the graphics window has the focus).
2102
2103 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
2104 @param onKeyPressed: a callback function called when a key is pressed
2105 '''
2106 self._onKeyPressed = onKeyPressed
2107
2109 '''
2110 Registers a callback that is invoked when a key is released (and the graphics window has the focus).
2111
2112 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function.
2113 @param onKeyReleased: a callback function called when a key is released
2114 '''
2115 self._onKeyReleased = onKeyReleased
2116
2118 '''
2119 Returns the screen width in pixels.
2120 '''
2121 screen_resolution = self._app.desktop().screenGeometry()
2122 return screen_resolution.width()
2123
2125 '''
2126 Returns the screen height in pixels.
2127 '''
2128 screen_resolution = self._app.desktop().screenGeometry()
2129 return screen_resolution.height()
2130
2131
2133 '''
2134 Sets the screen position to the center of the screen.
2135 '''
2136 frameGm = self.frameGeometry()
2137 centerPoint = QtGui.QDesktopWidget().availableGeometry().center()
2138 frameGm.moveCenter(centerPoint)
2139 super(GPanel, self).move(frameGm.topLeft())
2140
2142 '''
2143 Sets the screen position of the graphics window.
2144 @param ulx: the upper left corner's x-coordinate
2145 @param ulx: the upper left corner's y-coordinate
2146 '''
2147 super(GPanel, self).move(ulx, uly)
2148
2150 '''
2151 Saves the current graphics into a image buffer. Use restoreGraphics()
2152 to restore it.
2153 '''
2154 self._savePixmap = self._pixmap.copy(QRect())
2155
2157 '''
2158 Restores the saved graphics from the image buffer. Use saveGraphics()
2159 to save it.
2160 '''
2161 if self._savePixmap == None:
2162 raise Exception("Store graphics buffer is empty.")
2163 img = self._savePixmap.toImage()
2164 self._painter.drawImage(0, 0, img)
2165 if self._enableRepaint:
2166 self.repaint()
2167
2169 '''
2170 Performs pixel color XOR operation with the existing background pixel.
2171 Be aware that if the background is white, drawing with a white pen shows a black pixel.
2172 (Parameter not used, for TigerJython compatibility)
2173 '''
2174 self._painter.setCompositionMode(QPainter.RasterOp_SourceXorDestination)
2175
2176
2178 '''
2179 Resets the drawing mode to standard (overwriting).
2180 '''
2181 self._painter.setCompositionMode(QPainter.CompositionMode_SourceOver)
2182
2184 '''
2185 Sets the screen position (pixel coordinates of upper left corner).
2186 '''
2187 super(GPanel, self).move(ulx, uly)
2188
2190 '''
2191 Sets the window to the center of the screen.
2192 '''
2193 xc, yc = GPanel.getScreenCenter()
2194 self.windowPosition(xc - self.winWidth // 2, yc - self.winHeight // 2)
2195
2196
2197
2199 pos = QPoint(e.pos())
2200 self._isLeftMouseButton = (e.button() == Qt.LeftButton)
2201 self._isRightMouseButton = (e.button() == Qt.RightButton)
2202 if self._onMousePressed != None:
2203 self._onMousePressed(self.toUserX(pos.x()), self.toUserY(pos.y()))
2204
2206 pos = QPoint(e.pos())
2207 self._isLeftMouseButton = (e.button() == Qt.LeftButton)
2208 self._isRightMouseButton = (e.button() != Qt.RightButton)
2209 if self._onMouseReleased != None:
2210 self._onMouseReleased(self.toUserX(pos.x()), self.toUserY(pos.y()))
2211
2213
2214 if self._inMouseMoveCallback:
2215 return
2216 self._inMouseMoveCallback = True
2217 pos = QPoint(e.pos())
2218 if self._onMouseDragged != None:
2219 self._onMouseDragged(self.toUserX(pos.x()), self.toUserY(pos.y()))
2220 self._inMouseMoveCallback = False
2221
2222
2224 key = e.key()
2225 if self._onKeyPressed != None:
2226 self._onKeyPressed(key)
2227
2229 key = e.key()
2230 if self._onKeyReleased != None:
2231 self._onKeyReleased(key)
2232
2233
2234 @staticmethod
2235 - def loadImage(filename, pic_format = None):
2236 '''
2237 Returns a QImage of the picture loaded from the given file. For pic_format = None,
2238 the picture format is guessed from the file data.
2239 @param: the file path to the picture file
2240 @param pic_format: format of picture, supported: "None" (default), "GIF", "JPG",
2241 "BMP", "PNG", "PBM", "PGM", "PPM", "TIFF", "XBM" "XPM".
2242 '''
2243 img = QImage(filename, pic_format)
2244 return img
2245
2246 @staticmethod
2248 '''
2249 Returns a tuple with the RGBA values at given pixel position (pixel coordinates).
2250 @param image: the QImage reference
2251 @param xPix: the pixel x-coordinate
2252 @param yPix: the pixel y-coordinate
2253 '''
2254 c = image.pixel(xPix, yPix)
2255 return QColor(c).getRgb()
2256
2257 @staticmethod
2258 - def scale(image, scaleFactor):
2259 '''
2260 Returns a new QImage of the scaled picture of the given QImage.
2261 @param image: the original QImage reference
2262 @param scaleFactor: the scale factor
2263 '''
2264 width = int(image.width() * scaleFactor)
2265 img = image.scaledToWidth(width)
2266 return img
2267
2268 @staticmethod
2269 - def crop(image, x1, y1, x2, y2):
2270 '''
2271 Returns a QImage of the sub-area of the given QImage.
2272 @param image: the given QImage reference
2273 @param xPix: the pixel ulx-coordinate
2274 @param yPix: the pixel uly-coordinate
2275 '''
2276 width = abs(x2 - x1)
2277 height = abs(y2 - y1)
2278 img = image.copy(x1, y1, width, height)
2279 return img
2280
2281 @staticmethod
2283 '''
2284 Returns the tuple of user coordinates of the point on the line through the point pt1 = (x1, y1)
2285 and the point pt2 = (x2, y2) that is in distance ratio times the length from pt1 to pt2 from
2286 pt1. For ratio < 0 the point is in the opposite direction.
2287 3 parameteters: pt1, pt2 (complex/list/tuple), ratio
2288 5 parameteters: x1, y1, x2, y2, ratio
2289 '''
2290 v1 = (x1, y1)
2291 v2 = (x2, y2)
2292 dv = (v2[0] - v1[0], v2[1] - v1[1])
2293 v = (v1[0] + ratio * dv[0], v1[1] + ratio * dv[1])
2294 return v[0], v[1]
2295
2296 @staticmethod
2298
2299
2300 '''
2301 Fills a bounded single-colored region with
2302 the given color. The given point is part of the region and used
2303 to specify it.
2304 @param pm the pixmap containing the connected region
2305 @param pt a point inside the region
2306 @param oldColor the old color of the region (RGB list/tuple)
2307 @param newColor the new color of the region (RGB list/tuple)
2308 @return a new qImage with the transformed region
2309 '''
2310 image = pm.toImage()
2311 oldColor = QColor(oldColor[0], oldColor[1], oldColor[2]).rgb()
2312 newColor = QColor(newColor[0], newColor[1], newColor[2]).rgb()
2313 q = [pt]
2314
2315
2316 while len(q) > 0:
2317 n = q.pop(0)
2318 if QColor(image.pixel(n[0], n[1])).rgb() != oldColor:
2319 continue
2320
2321 w = n
2322 e = [n[0] + 1, n[1]]
2323 while w[0] > 0 and QColor(image.pixel(w[0], w[1])).rgb() == oldColor:
2324 image.setPixel(w[0], w[1], newColor)
2325 if w[1] > 0 and QColor(image.pixel(w[0], w[1] - 1)).rgb() == oldColor:
2326 q.append([w[0], w[1] - 1])
2327 if w[1] < image.height() - 1 and QColor(image.pixel(w[0], w[1] + 1)).rgb() == oldColor:
2328 q.append([w[0], w[1] + 1])
2329 w[0] -= 1
2330
2331 while e[0] < image.width() - 1 and QColor(image.pixel(e[0], e[1])).rgb() == oldColor:
2332 image.setPixel(e[0], e[1], newColor)
2333 if e[1] > 0 and QColor(image.pixel(e[0], e[1] - 1)).rgb() == oldColor:
2334 q.append([e[0], e[1] - 1])
2335 if e[1] < image.height() - 1 and QColor(image.pixel(e[0], e[1] + 1)).rgb() == oldColor:
2336 q.append([e[0], e[1] + 1])
2337 e[0] += 1
2338 return image
2339
2340 @staticmethod
2342 '''
2343 Returns a random X11 color string.
2344 '''
2345 r = random.randint(0, 540)
2346 c = x11ColorDict.keys()
2347 return c[r]
2348
2349 @staticmethod
2351 '''
2352 Returns x, y coordinates tuple of the screen's center point.
2353 '''
2354 centerPoint = QtGui.QDesktopWidget().availableGeometry().center()
2355 return centerPoint.x(), centerPoint.y()
2356
2357
2358 '''
2359 Subclass of GPanel to be used as embedded QWidget in a GUI dialog (QDialog).
2360 '''
2362
2364 '''
2365 Creates a GPanel with no application window.
2366 '''
2367 super(GPane, self).__init__(*args, embedded = True)
2368
2369
2370
2371 '''
2372 X11 to RGB color mapping
2373 '''
2374 x11ColorDict = {
2375 "aqua":[0, 255, 255],
2376 "cornflower":[100, 149, 237],
2377 "crimson":[220, 20, 60],
2378 "fuchsia":[255, 0, 255],
2379 "indigo":[75, 0, 130],
2380 "lime":[50, 205, 50],
2381 "silver":[192, 192, 192],
2382 "ghost white":[248, 248, 255],
2383 "snow":[255, 250, 250],
2384 "ghostwhite":[248, 248, 255],
2385 "white smoke":[245, 245, 245],
2386 "whitesmoke":[245, 245, 245],
2387 "gainsboro":[220, 220, 220],
2388 "floral white":[255, 250, 240],
2389 "floralwhite":[255, 250, 240],
2390 "old lace":[253, 245, 230],
2391 "oldlace":[253, 245, 230],
2392 "linen":[250, 240, 230],
2393 "antique white":[250, 235, 215],
2394 "antiquewhite":[250, 235, 215],
2395 "papaya whip":[255, 239, 213],
2396 "papayawhip":[255, 239, 213],
2397 "blanched almond":[255, 235, 205],
2398 "blanchedalmond":[255, 235, 205],
2399 "bisque":[255, 228, 196],
2400 "peach puff":[255, 218, 185],
2401 "peachpuff":[255, 218, 185],
2402 "navajo white":[255, 222, 173],
2403 "navajowhite":[255, 222, 173],
2404 "moccasin":[255, 228, 181],
2405 "cornsilk":[255, 248, 220],
2406 "ivory":[255, 255, 240],
2407 "lemon chiffon":[255, 250, 205],
2408 "lemonchiffon":[255, 250, 205],
2409 "seashell":[255, 245, 238],
2410 "honeydew":[240, 255, 240],
2411 "mint cream":[245, 255, 250],
2412 "mintcream":[245, 255, 250],
2413 "azure":[240, 255, 255],
2414 "alice blue":[240, 248, 255],
2415 "aliceblue":[240, 248, 255],
2416 "lavender":[230, 230, 250],
2417 "lavender blush":[255, 240, 245],
2418 "lavenderblush":[255, 240, 245],
2419 "misty rose":[255, 228, 225],
2420 "mistyrose":[255, 228, 225],
2421 "white":[255, 255, 255],
2422 "black":[0, 0, 0],
2423 "dark slate gray":[47, 79, 79],
2424 "darkslategray":[47, 79, 79],
2425 "dark slate grey":[47, 79, 79],
2426 "darkslategrey":[47, 79, 79],
2427 "dim gray":[105, 105, 105],
2428 "dimgray":[105, 105, 105],
2429 "dim grey":[105, 105, 105],
2430 "dimgrey":[105, 105, 105],
2431 "slate gray":[112, 128, 144],
2432 "slategray":[112, 128, 144],
2433 "slate grey":[112, 128, 144],
2434 "slategrey":[112, 128, 144],
2435 "light slate gray":[119, 136, 153],
2436 "lightslategray":[119, 136, 153],
2437 "light slate grey":[119, 136, 153],
2438 "lightslategrey":[119, 136, 153],
2439 "gray":[190, 190, 190],
2440 "grey":[190, 190, 190],
2441 "light grey":[211, 211, 211],
2442 "lightgrey":[211, 211, 211],
2443 "light gray":[211, 211, 211],
2444 "lightgray":[211, 211, 211],
2445 "midnight blue":[25, 25, 112],
2446 "midnightblue":[25, 25, 112],
2447 "navy":[0, 0, 128],
2448 "navy blue":[0, 0, 128],
2449 "navyblue":[0, 0, 128],
2450 "cornflower blue":[100, 149, 237],
2451 "cornflowerblue":[100, 149, 237],
2452 "dark slate blue":[72, 61, 139],
2453 "darkslateblue":[72, 61, 139],
2454 "slate blue":[106, 90, 205],
2455 "slateblue":[106, 90, 205],
2456 "medium slate blue":[123, 104, 238],
2457 "mediumslateblue":[123, 104, 238],
2458 "light slate blue":[132, 112, 255],
2459 "lightslateblue":[132, 112, 255],
2460 "medium blue":[0, 0, 205],
2461 "mediumblue":[0, 0, 205],
2462 "royal blue":[65, 105, 225],
2463 "royalblue":[65, 105, 225],
2464 "blue":[0, 0, 255],
2465 "dodger blue":[30, 144, 255],
2466 "dodgerblue":[30, 144, 255],
2467 "deep sky blue":[0, 191, 255],
2468 "deepskyblue":[0, 191, 255],
2469 "sky blue":[135, 206, 235],
2470 "skyblue":[135, 206, 235],
2471 "light sky blue":[135, 206, 250],
2472 "lightskyblue":[135, 206, 250],
2473 "steel blue":[70, 130, 180],
2474 "steelblue":[70, 130, 180],
2475 "light steel blue":[176, 196, 222],
2476 "lightsteelblue":[176, 196, 222],
2477 "light blue":[173, 216, 230],
2478 "lightblue":[173, 216, 230],
2479 "powder blue":[176, 224, 230],
2480 "powderblue":[176, 224, 230],
2481 "pale turquoise":[175, 238, 238],
2482 "paleturquoise":[175, 238, 238],
2483 "dark turquoise":[0, 206, 209],
2484 "darkturquoise":[0, 206, 209],
2485 "medium turquoise":[72, 209, 204],
2486 "mediumturquoise":[72, 209, 204],
2487 "turquoise":[64, 224, 208],
2488 "cyan":[0, 255, 255],
2489 "light cyan":[224, 255, 255],
2490 "lightcyan":[224, 255, 255],
2491 "cadet blue":[95, 158, 160],
2492 "cadetblue":[95, 158, 160],
2493 "medium aquamarine":[102, 205, 170],
2494 "mediumaquamarine":[102, 205, 170],
2495 "aquamarine":[127, 255, 212],
2496 "dark green":[0, 100, 0],
2497 "darkgreen":[0, 100, 0],
2498 "dark olive green":[85, 107, 47],
2499 "darkolivegreen":[85, 107, 47],
2500 "dark sea green":[143, 188, 143],
2501 "darkseagreen":[143, 188, 143],
2502 "sea green":[46, 139, 87],
2503 "seagreen":[46, 139, 87],
2504 "medium sea green":[60, 179, 113],
2505 "mediumseagreen":[60, 179, 113],
2506 "light sea green":[32, 178, 170],
2507 "lightseagreen":[32, 178, 170],
2508 "pale green":[152, 251, 152],
2509 "palegreen":[152, 251, 152],
2510 "spring green":[0, 255, 127],
2511 "springgreen":[0, 255, 127],
2512 "lawn green":[124, 252, 0],
2513 "lawngreen":[124, 252, 0],
2514 "green":[0, 255, 0],
2515 "chartreuse":[127, 255, 0],
2516 "medium spring green":[0, 250, 154],
2517 "mediumspringgreen":[0, 250, 154],
2518 "green yellow":[173, 255, 47],
2519 "greenyellow":[173, 255, 47],
2520 "lime green":[50, 205, 50],
2521 "limegreen":[50, 205, 50],
2522 "yellow green":[154, 205, 50],
2523 "yellowgreen":[154, 205, 50],
2524 "forest green":[34, 139, 34],
2525 "forestgreen":[34, 139, 34],
2526 "olive drab":[107, 142, 35],
2527 "olivedrab":[107, 142, 35],
2528 "dark khaki":[189, 183, 107],
2529 "darkkhaki":[189, 183, 107],
2530 "khaki":[240, 230, 140],
2531 "pale goldenrod":[238, 232, 170],
2532 "palegoldenrod":[238, 232, 170],
2533 "light goldenrod yellow":[250, 250, 210],
2534 "lightgoldenrodyellow":[250, 250, 210],
2535 "light yellow":[255, 255, 224],
2536 "lightyellow":[255, 255, 224],
2537 "yellow":[255, 255, 0],
2538 "gold":[255, 215, 0],
2539 "light goldenrod":[238, 221, 130],
2540 "lightgoldenrod":[238, 221, 130],
2541 "goldenrod":[218, 165, 32],
2542 "dark goldenrod":[184, 134, 11],
2543 "darkgoldenrod":[184, 134, 11],
2544 "rosy brown":[188, 143, 143],
2545 "rosybrown":[188, 143, 143],
2546 "indian red":[205, 92, 92],
2547 "indianred":[205, 92, 92],
2548 "saddle brown":[139, 69, 19],
2549 "saddlebrown":[139, 69, 19],
2550 "sienna":[160, 82, 45],
2551 "peru":[205, 133, 63],
2552 "burlywood":[222, 184, 135],
2553 "beige":[245, 245, 220],
2554 "wheat":[245, 222, 179],
2555 "sandy brown":[244, 164, 96],
2556 "sandybrown":[244, 164, 96],
2557 "tan":[210, 180, 140],
2558 "chocolate":[210, 105, 30],
2559 "firebrick":[178, 34, 34],
2560 "brown":[165, 42, 42],
2561 "dark salmon":[233, 150, 122],
2562 "darksalmon":[233, 150, 122],
2563 "salmon":[250, 128, 114],
2564 "light salmon":[255, 160, 122],
2565 "lightsalmon":[255, 160, 122],
2566 "orange":[255, 165, 0],
2567 "dark orange":[255, 140, 0],
2568 "darkorange":[255, 140, 0],
2569 "coral":[255, 127, 80],
2570 "light coral":[240, 128, 128],
2571 "lightcoral":[240, 128, 128],
2572 "tomato":[255, 99, 71],
2573 "orange red":[255, 69, 0],
2574 "orangered":[255, 69, 0],
2575 "red":[255, 0, 0],
2576 "hot pink":[255, 105, 180],
2577 "hotpink":[255, 105, 180],
2578 "deep pink":[255, 20, 147],
2579 "deeppink":[255, 20, 147],
2580 "pink":[255, 192, 203],
2581 "light pink":[255, 182, 193],
2582 "lightpink":[255, 182, 193],
2583 "pale violet red":[219, 112, 147],
2584 "palevioletred":[219, 112, 147],
2585 "maroon":[176, 48, 96],
2586 "medium violet red":[199, 21, 133],
2587 "mediumvioletred":[199, 21, 133],
2588 "violet red":[208, 32, 144],
2589 "violetred":[208, 32, 144],
2590 "magenta":[255, 0, 255],
2591 "violet":[238, 130, 238],
2592 "plum":[221, 160, 221],
2593 "orchid":[218, 112, 214],
2594 "medium orchid":[186, 85, 211],
2595 "mediumorchid":[186, 85, 211],
2596 "dark orchid":[153, 50, 204],
2597 "darkorchid":[153, 50, 204],
2598 "dark violet":[148, 0, 211],
2599 "darkviolet":[148, 0, 211],
2600 "blue violet":[138, 43, 226],
2601 "blueviolet":[138, 43, 226],
2602 "purple":[160, 32, 240],
2603 "medium purple":[147, 112, 219],
2604 "mediumpurple":[147, 112, 219],
2605 "thistle":[216, 191, 216],
2606 "snow1":[255, 250, 250],
2607 "snow2":[238, 233, 233],
2608 "snow3":[205, 201, 201],
2609 "snow4":[139, 137, 137],
2610 "seashell1":[255, 245, 238],
2611 "seashell2":[238, 229, 222],
2612 "seashell3":[205, 197, 191],
2613 "seashell4":[139, 134, 130],
2614 "antiquewhite1":[255, 239, 219],
2615 "antiquewhite2":[238, 223, 204],
2616 "antiquewhite3":[205, 192, 176],
2617 "antiquewhite4":[139, 131, 120],
2618 "bisque1":[255, 228, 196],
2619 "bisque2":[238, 213, 183],
2620 "bisque3":[205, 183, 158],
2621 "bisque4":[139, 125, 107],
2622 "peachpuff1":[255, 218, 185],
2623 "peachpuff2":[238, 203, 173],
2624 "peachpuff3":[205, 175, 149],
2625 "peachpuff4":[139, 119, 101],
2626 "navajowhite1":[255, 222, 173],
2627 "navajowhite2":[238, 207, 161],
2628 "navajowhite3":[205, 179, 139],
2629 "navajowhite4":[139, 121, 94],
2630 "lemonchiffon1":[255, 250, 205],
2631 "lemonchiffon2":[238, 233, 191],
2632 "lemonchiffon3":[205, 201, 165],
2633 "lemonchiffon4":[139, 137, 112],
2634 "cornsilk1":[255, 248, 220],
2635 "cornsilk2":[238, 232, 205],
2636 "cornsilk3":[205, 200, 177],
2637 "cornsilk4":[139, 136, 120],
2638 "ivory1":[255, 255, 240],
2639 "ivory2":[238, 238, 224],
2640 "ivory3":[205, 205, 193],
2641 "ivory4":[139, 139, 131],
2642 "honeydew1":[240, 255, 240],
2643 "honeydew2":[224, 238, 224],
2644 "honeydew3":[193, 205, 193],
2645 "honeydew4":[131, 139, 131],
2646 "lavenderblush1":[255, 240, 245],
2647 "lavenderblush2":[238, 224, 229],
2648 "lavenderblush3":[205, 193, 197],
2649 "lavenderblush4":[139, 131, 134],
2650 "mistyrose1":[255, 228, 225],
2651 "mistyrose2":[238, 213, 210],
2652 "mistyrose3":[205, 183, 181],
2653 "mistyrose4":[139, 125, 123],
2654 "azure1":[240, 255, 255],
2655 "azure2":[224, 238, 238],
2656 "azure3":[193, 205, 205],
2657 "azure4":[131, 139, 139],
2658 "slateblue1":[131, 111, 255],
2659 "slateblue2":[122, 103, 238],
2660 "slateblue3":[105, 89, 205],
2661 "slateblue4":[71, 60, 139],
2662 "royalblue1":[72, 118, 255],
2663 "royalblue2":[67, 110, 238],
2664 "royalblue3":[58, 95, 205],
2665 "royalblue4":[39, 64, 139],
2666 "blue1":[0, 0, 255],
2667 "blue2":[0, 0, 238],
2668 "blue3":[0, 0, 205],
2669 "blue4":[0, 0, 139],
2670 "dodgerblue1":[30, 144, 255],
2671 "dodgerblue2":[28, 134, 238],
2672 "dodgerblue3":[24, 116, 205],
2673 "dodgerblue4":[16, 78, 139],
2674 "steelblue1":[99, 184, 255],
2675 "steelblue2":[92, 172, 238],
2676 "steelblue3":[79, 148, 205],
2677 "steelblue4":[54, 100, 139],
2678 "deepskyblue1":[0, 191, 255],
2679 "deepskyblue2":[0, 178, 238],
2680 "deepskyblue3":[0, 154, 205],
2681 "deepskyblue4":[0, 104, 139],
2682 "skyblue1":[135, 206, 255],
2683 "skyblue2":[126, 192, 238],
2684 "skyblue3":[108, 166, 205],
2685 "skyblue4":[74, 112, 139],
2686 "lightskyblue1":[176, 226, 255],
2687 "lightskyblue2":[164, 211, 238],
2688 "lightskyblue3":[141, 182, 205],
2689 "lightskyblue4":[96, 123, 139],
2690 "slategray1":[198, 226, 255],
2691 "slategray2":[185, 211, 238],
2692 "slategray3":[159, 182, 205],
2693 "slategray4":[108, 123, 139],
2694 "lightsteelblue1":[202, 225, 255],
2695 "lightsteelblue2":[188, 210, 238],
2696 "lightsteelblue3":[162, 181, 205],
2697 "lightsteelblue4":[110, 123, 139],
2698 "lightblue1":[191, 239, 255],
2699 "lightblue2":[178, 223, 238],
2700 "lightblue3":[154, 192, 205],
2701 "lightblue4":[104, 131, 139],
2702 "lightcyan1":[224, 255, 255],
2703 "lightcyan2":[209, 238, 238],
2704 "lightcyan3":[180, 205, 205],
2705 "lightcyan4":[122, 139, 139],
2706 "paleturquoise1":[187, 255, 255],
2707 "paleturquoise2":[174, 238, 238],
2708 "paleturquoise3":[150, 205, 205],
2709 "paleturquoise4":[102, 139, 139],
2710 "cadetblue1":[152, 245, 255],
2711 "cadetblue2":[142, 229, 238],
2712 "cadetblue3":[122, 197, 205],
2713 "cadetblue4":[83, 134, 139],
2714 "turquoise1":[0, 245, 255],
2715 "turquoise2":[0, 229, 238],
2716 "turquoise3":[0, 197, 205],
2717 "turquoise4":[0, 134, 139],
2718 "cyan1":[0, 255, 255],
2719 "cyan2":[0, 238, 238],
2720 "cyan3":[0, 205, 205],
2721 "cyan4":[0, 139, 139],
2722 "darkslategray1":[151, 255, 255],
2723 "darkslategray2":[141, 238, 238],
2724 "darkslategray3":[121, 205, 205],
2725 "darkslategray4":[82, 139, 139],
2726 "aquamarine1":[127, 255, 212],
2727 "aquamarine2":[118, 238, 198],
2728 "aquamarine3":[102, 205, 170],
2729 "aquamarine4":[69, 139, 116],
2730 "darkseagreen1":[193, 255, 193],
2731 "darkseagreen2":[180, 238, 180],
2732 "darkseagreen3":[155, 205, 155],
2733 "darkseagreen4":[105, 139, 105],
2734 "seagreen1":[84, 255, 159],
2735 "seagreen2":[78, 238, 148],
2736 "seagreen3":[67, 205, 128],
2737 "seagreen4":[46, 139, 87],
2738 "palegreen1":[154, 255, 154],
2739 "palegreen2":[144, 238, 144],
2740 "palegreen3":[124, 205, 124],
2741 "palegreen4":[84, 139, 84],
2742 "springgreen1":[0, 255, 127],
2743 "springgreen2":[0, 238, 118],
2744 "springgreen3":[0, 205, 102],
2745 "springgreen4":[0, 139, 69],
2746 "green1":[0, 255, 0],
2747 "green2":[0, 238, 0],
2748 "green3":[0, 205, 0],
2749 "green4":[0, 139, 0],
2750 "chartreuse1":[127, 255, 0],
2751 "chartreuse2":[118, 238, 0],
2752 "chartreuse3":[102, 205, 0],
2753 "chartreuse4":[69, 139, 0],
2754 "olivedrab1":[192, 255, 62],
2755 "olivedrab2":[179, 238, 58],
2756 "olivedrab3":[154, 205, 50],
2757 "olivedrab4":[105, 139, 34],
2758 "darkolivegreen1":[202, 255, 112],
2759 "darkolivegreen2":[188, 238, 104],
2760 "darkolivegreen3":[162, 205, 90],
2761 "darkolivegreen4":[110, 139, 61],
2762 "khaki1":[255, 246, 143],
2763 "khaki2":[238, 230, 133],
2764 "khaki3":[205, 198, 115],
2765 "khaki4":[139, 134, 78],
2766 "lightgoldenrod1":[255, 236, 139],
2767 "lightgoldenrod2":[238, 220, 130],
2768 "lightgoldenrod3":[205, 190, 112],
2769 "lightgoldenrod4":[139, 129, 76],
2770 "lightyellow1":[255, 255, 224],
2771 "lightyellow2":[238, 238, 209],
2772 "lightyellow3":[205, 205, 180],
2773 "lightyellow4":[139, 139, 122],
2774 "yellow1":[255, 255, 0],
2775 "yellow2":[238, 238, 0],
2776 "yellow3":[205, 205, 0],
2777 "yellow4":[139, 139, 0],
2778 "gold1":[255, 215, 0],
2779 "gold2":[238, 201, 0],
2780 "gold3":[205, 173, 0],
2781 "gold4":[139, 117, 0],
2782 "goldenrod1":[255, 193, 37],
2783 "goldenrod2":[238, 180, 34],
2784 "goldenrod3":[205, 155, 29],
2785 "goldenrod4":[139, 105, 20],
2786 "darkgoldenrod1":[255, 185, 15],
2787 "darkgoldenrod2":[238, 173, 14],
2788 "darkgoldenrod3":[205, 149, 12],
2789 "darkgoldenrod4":[139, 101, 8],
2790 "rosybrown1":[255, 193, 193],
2791 "rosybrown2":[238, 180, 180],
2792 "rosybrown3":[205, 155, 155],
2793 "rosybrown4":[139, 105, 105],
2794 "indianred1":[255, 106, 106],
2795 "indianred2":[238, 99, 99],
2796 "indianred3":[205, 85, 85],
2797 "indianred4":[139, 58, 58],
2798 "sienna1":[255, 130, 71],
2799 "sienna2":[238, 121, 66],
2800 "sienna3":[205, 104, 57],
2801 "sienna4":[139, 71, 38],
2802 "burlywood1":[255, 211, 155],
2803 "burlywood2":[238, 197, 145],
2804 "burlywood3":[205, 170, 125],
2805 "burlywood4":[139, 115, 85],
2806 "wheat1":[255, 231, 186],
2807 "wheat2":[238, 216, 174],
2808 "wheat3":[205, 186, 150],
2809 "wheat4":[139, 126, 102],
2810 "tan1":[255, 165, 79],
2811 "tan2":[238, 154, 73],
2812 "tan3":[205, 133, 63],
2813 "tan4":[139, 90, 43],
2814 "chocolate1":[255, 127, 36],
2815 "chocolate2":[238, 118, 33],
2816 "chocolate3":[205, 102, 29],
2817 "chocolate4":[139, 69, 19],
2818 "firebrick1":[255, 48, 48],
2819 "firebrick2":[238, 44, 44],
2820 "firebrick3":[205, 38, 38],
2821 "firebrick4":[139, 26, 26],
2822 "brown1":[255, 64, 64],
2823 "brown2":[238, 59, 59],
2824 "brown3":[205, 51, 51],
2825 "brown4":[139, 35, 35],
2826 "salmon1":[255, 140, 105],
2827 "salmon2":[238, 130, 98],
2828 "salmon3":[205, 112, 84],
2829 "salmon4":[139, 76, 57],
2830 "lightsalmon1":[255, 160, 122],
2831 "lightsalmon2":[238, 149, 114],
2832 "lightsalmon3":[205, 129, 98],
2833 "lightsalmon4":[139, 87, 66],
2834 "orange1":[255, 165, 0],
2835 "orange2":[238, 154, 0],
2836 "orange3":[205, 133, 0],
2837 "orange4":[139, 90, 0],
2838 "darkorange1":[255, 127, 0],
2839 "darkorange2":[238, 118, 0],
2840 "darkorange3":[205, 102, 0],
2841 "darkorange4":[139, 69, 0],
2842 "coral1":[255, 114, 86],
2843 "coral2":[238, 106, 80],
2844 "coral3":[205, 91, 69],
2845 "coral4":[139, 62, 47],
2846 "tomato1":[255, 99, 71],
2847 "tomato2":[238, 92, 66],
2848 "tomato3":[205, 79, 57],
2849 "tomato4":[139, 54, 38],
2850 "orangered1":[255, 69, 0],
2851 "orangered2":[238, 64, 0],
2852 "orangered3":[205, 55, 0],
2853 "orangered4":[139, 37, 0],
2854 "red1":[255, 0, 0],
2855 "red2":[238, 0, 0],
2856 "red3":[205, 0, 0],
2857 "red4":[139, 0, 0],
2858 "deeppink1":[255, 20, 147],
2859 "deeppink2":[238, 18, 137],
2860 "deeppink3":[205, 16, 118],
2861 "deeppink4":[139, 10, 80],
2862 "hotpink1":[255, 110, 180],
2863 "hotpink2":[238, 106, 167],
2864 "hotpink3":[205, 96, 144],
2865 "hotpink4":[139, 58, 98],
2866 "pink1":[255, 181, 197],
2867 "pink2":[238, 169, 184],
2868 "pink3":[205, 145, 158],
2869 "pink4":[139, 99, 108],
2870 "lightpink1":[255, 174, 185],
2871 "lightpink2":[238, 162, 173],
2872 "lightpink3":[205, 140, 149],
2873 "lightpink4":[139, 95, 101],
2874 "palevioletred1":[255, 130, 171],
2875 "palevioletred2":[238, 121, 159],
2876 "palevioletred3":[205, 104, 137],
2877 "palevioletred4":[139, 71, 93],
2878 "maroon1":[255, 52, 179],
2879 "maroon2":[238, 48, 167],
2880 "maroon3":[205, 41, 144],
2881 "maroon4":[139, 28, 98],
2882 "violetred1":[255, 62, 150],
2883 "violetred2":[238, 58, 140],
2884 "violetred3":[205, 50, 120],
2885 "violetred4":[139, 34, 82],
2886 "magenta1":[255, 0, 255],
2887 "magenta2":[238, 0, 238],
2888 "magenta3":[205, 0, 205],
2889 "magenta4":[139, 0, 139],
2890 "orchid1":[255, 131, 250],
2891 "orchid2":[238, 122, 233],
2892 "orchid3":[205, 105, 201],
2893 "orchid4":[139, 71, 137],
2894 "plum1":[255, 187, 255],
2895 "plum2":[238, 174, 238],
2896 "plum3":[205, 150, 205],
2897 "plum4":[139, 102, 139],
2898 "mediumorchid1":[224, 102, 255],
2899 "mediumorchid2":[209, 95, 238],
2900 "mediumorchid3":[180, 82, 205],
2901 "mediumorchid4":[122, 55, 139],
2902 "darkorchid1":[191, 62, 255],
2903 "darkorchid2":[178, 58, 238],
2904 "darkorchid3":[154, 50, 205],
2905 "darkorchid4":[104, 34, 139],
2906 "purple1":[155, 48, 255],
2907 "purple2":[145, 44, 238],
2908 "purple3":[125, 38, 205],
2909 "purple4":[85, 26, 139],
2910 "mediumpurple1":[171, 130, 255],
2911 "mediumpurple2":[159, 121, 238],
2912 "mediumpurple3":[137, 104, 205],
2913 "mediumpurple4":[93, 71, 139],
2914 "thistle1":[255, 225, 255],
2915 "thistle2":[238, 210, 238],
2916 "thistle3":[205, 181, 205],
2917 "thistle4":[139, 123, 139],
2918 "gray0":[0, 0, 0],
2919 "grey0":[0, 0, 0],
2920 "gray1":[3, 3, 3],
2921 "grey1":[3, 3, 3],
2922 "gray2":[5, 5, 5],
2923 "grey2":[5, 5, 5],
2924 "gray3":[8, 8, 8],
2925 "grey3":[8, 8, 8],
2926 "gray4":[10, 10, 10],
2927 "grey4":[10, 10, 10],
2928 "gray5":[13, 13, 13],
2929 "grey5":[13, 13, 13],
2930 "gray6":[15, 15, 15],
2931 "grey6":[15, 15, 15],
2932 "gray7":[18, 18, 18],
2933 "grey7":[18, 18, 18],
2934 "gray8":[20, 20, 20],
2935 "grey8":[20, 20, 20],
2936 "gray9":[23, 23, 23],
2937 "grey9":[23, 23, 23],
2938 "gray10":[26, 26, 26],
2939 "grey10":[26, 26, 26],
2940 "gray11":[28, 28, 28],
2941 "grey11":[28, 28, 28],
2942 "gray12":[31, 31, 31],
2943 "grey12":[31, 31, 31],
2944 "gray13":[33, 33, 33],
2945 "grey13":[33, 33, 33],
2946 "gray14":[36, 36, 36],
2947 "grey14":[36, 36, 36],
2948 "gray15":[38, 38, 38],
2949 "grey15":[38, 38, 38],
2950 "gray16":[41, 41, 41],
2951 "grey16":[41, 41, 41],
2952 "gray17":[43, 43, 43],
2953 "grey17":[43, 43, 43],
2954 "gray18":[46, 46, 46],
2955 "grey18":[46, 46, 46],
2956 "gray19":[48, 48, 48],
2957 "grey19":[48, 48, 48],
2958 "gray20":[51, 51, 51],
2959 "grey20":[51, 51, 51],
2960 "gray21":[54, 54, 54],
2961 "grey21":[54, 54, 54],
2962 "gray22":[56, 56, 56],
2963 "grey22":[56, 56, 56],
2964 "gray23":[59, 59, 59],
2965 "grey23":[59, 59, 59],
2966 "gray24":[61, 61, 61],
2967 "grey24":[61, 61, 61],
2968 "gray25":[64, 64, 64],
2969 "grey25":[64, 64, 64],
2970 "gray26":[66, 66, 66],
2971 "grey26":[66, 66, 66],
2972 "gray27":[69, 69, 69],
2973 "grey27":[69, 69, 69],
2974 "gray28":[71, 71, 71],
2975 "grey28":[71, 71, 71],
2976 "gray29":[74, 74, 74],
2977 "grey29":[74, 74, 74],
2978 "gray30":[77, 77, 77],
2979 "grey30":[77, 77, 77],
2980 "gray31":[79, 79, 79],
2981 "grey31":[79, 79, 79],
2982 "gray32":[82, 82, 82],
2983 "grey32":[82, 82, 82],
2984 "gray33":[84, 84, 84],
2985 "grey33":[84, 84, 84],
2986 "gray34":[87, 87, 87],
2987 "grey34":[87, 87, 87],
2988 "gray35":[89, 89, 89],
2989 "grey35":[89, 89, 89],
2990 "gray36":[92, 92, 92],
2991 "grey36":[92, 92, 92],
2992 "gray37":[94, 94, 94],
2993 "grey37":[94, 94, 94],
2994 "gray38":[97, 97, 97],
2995 "grey38":[97, 97, 97],
2996 "gray39":[99, 99, 99],
2997 "grey39":[99, 99, 99],
2998 "gray40":[102, 102, 102],
2999 "grey40":[102, 102, 102],
3000 "gray41":[105, 105, 105],
3001 "grey41":[105, 105, 105],
3002 "gray42":[107, 107, 107],
3003 "grey42":[107, 107, 107],
3004 "gray43":[110, 110, 110],
3005 "grey43":[110, 110, 110],
3006 "gray44":[112, 112, 112],
3007 "grey44":[112, 112, 112],
3008 "gray45":[115, 115, 115],
3009 "grey45":[115, 115, 115],
3010 "gray46":[117, 117, 117],
3011 "grey46":[117, 117, 117],
3012 "gray47":[120, 120, 120],
3013 "grey47":[120, 120, 120],
3014 "gray48":[122, 122, 122],
3015 "grey48":[122, 122, 122],
3016 "gray49":[125, 125, 125],
3017 "grey49":[125, 125, 125],
3018 "gray50":[127, 127, 127],
3019 "grey50":[127, 127, 127],
3020 "gray51":[130, 130, 130],
3021 "grey51":[130, 130, 130],
3022 "gray52":[133, 133, 133],
3023 "grey52":[133, 133, 133],
3024 "gray53":[135, 135, 135],
3025 "grey53":[135, 135, 135],
3026 "gray54":[138, 138, 138],
3027 "grey54":[138, 138, 138],
3028 "gray55":[140, 140, 140],
3029 "grey55":[140, 140, 140],
3030 "gray56":[143, 143, 143],
3031 "grey56":[143, 143, 143],
3032 "gray57":[145, 145, 145],
3033 "grey57":[145, 145, 145],
3034 "gray58":[148, 148, 148],
3035 "grey58":[148, 148, 148],
3036 "gray59":[150, 150, 150],
3037 "grey59":[150, 150, 150],
3038 "gray60":[153, 153, 153],
3039 "grey60":[153, 153, 153],
3040 "gray61":[156, 156, 156],
3041 "grey61":[156, 156, 156],
3042 "gray62":[158, 158, 158],
3043 "grey62":[158, 158, 158],
3044 "gray63":[161, 161, 161],
3045 "grey63":[161, 161, 161],
3046 "gray64":[163, 163, 163],
3047 "grey64":[163, 163, 163],
3048 "gray65":[166, 166, 166],
3049 "grey65":[166, 166, 166],
3050 "gray66":[168, 168, 168],
3051 "grey66":[168, 168, 168],
3052 "gray67":[171, 171, 171],
3053 "grey67":[171, 171, 171],
3054 "gray68":[173, 173, 173],
3055 "grey68":[173, 173, 173],
3056 "gray69":[176, 176, 176],
3057 "grey69":[176, 176, 176],
3058 "gray70":[179, 179, 179],
3059 "grey70":[179, 179, 179],
3060 "gray71":[181, 181, 181],
3061 "grey71":[181, 181, 181],
3062 "gray72":[184, 184, 184],
3063 "grey72":[184, 184, 184],
3064 "gray73":[186, 186, 186],
3065 "grey73":[186, 186, 186],
3066 "gray74":[189, 189, 189],
3067 "grey74":[189, 189, 189],
3068 "gray75":[191, 191, 191],
3069 "grey75":[191, 191, 191],
3070 "gray76":[194, 194, 194],
3071 "grey76":[194, 194, 194],
3072 "gray77":[196, 196, 196],
3073 "grey77":[196, 196, 196],
3074 "gray78":[199, 199, 199],
3075 "grey78":[199, 199, 199],
3076 "gray79":[201, 201, 201],
3077 "grey79":[201, 201, 201],
3078 "gray80":[204, 204, 204],
3079 "grey80":[204, 204, 204],
3080 "gray81":[207, 207, 207],
3081 "grey81":[207, 207, 207],
3082 "gray82":[209, 209, 209],
3083 "grey82":[209, 209, 209],
3084 "gray83":[212, 212, 212],
3085 "grey83":[212, 212, 212],
3086 "gray84":[214, 214, 214],
3087 "grey84":[214, 214, 214],
3088 "gray85":[217, 217, 217],
3089 "grey85":[217, 217, 217],
3090 "gray86":[219, 219, 219],
3091 "grey86":[219, 219, 219],
3092 "gray87":[222, 222, 222],
3093 "grey87":[222, 222, 222],
3094 "gray88":[224, 224, 224],
3095 "grey88":[224, 224, 224],
3096 "gray89":[227, 227, 227],
3097 "grey89":[227, 227, 227],
3098 "gray90":[229, 229, 229],
3099 "grey90":[229, 229, 229],
3100 "gray91":[232, 232, 232],
3101 "grey91":[232, 232, 232],
3102 "gray92":[235, 235, 235],
3103 "grey92":[235, 235, 235],
3104 "gray93":[237, 237, 237],
3105 "grey93":[237, 237, 237],
3106 "gray94":[240, 240, 240],
3107 "grey94":[240, 240, 240],
3108 "gray95":[242, 242, 242],
3109 "grey95":[242, 242, 242],
3110 "gray96":[245, 245, 245],
3111 "grey96":[245, 245, 245],
3112 "gray97":[247, 247, 247],
3113 "grey97":[247, 247, 247],
3114 "gray98":[250, 250, 250],
3115 "grey98":[250, 250, 250],
3116 "gray99":[252, 252, 252],
3117 "grey99":[252, 252, 252],
3118 "gray100":[255, 255, 255],
3119 "grey100":[255, 255, 255],
3120 "dark grey":[169, 169, 169],
3121 "darkgrey":[169, 169, 169],
3122 "dark gray":[169, 169, 169],
3123 "darkgray":[169, 169, 169],
3124 "dark blue":[0, 0, 139],
3125 "darkblue":[0, 0, 139],
3126 "dark cyan":[0, 139, 139],
3127 "darkcyan":[0, 139, 139],
3128 "dark magenta":[139, 0, 139],
3129 "darkmagenta":[139, 0, 139],
3130 "dark red":[139, 0, 0],
3131 "darkred":[139, 0, 0],
3132 "light green":[144, 238, 144],
3133 "lightgreen":[144, 238, 144],
3134 "olive":[128, 128, 0],
3135 "teal":[0, 128, 128]}
3136
3137
3138
3139
3140 '''
3141 The key names used by Qt.
3142 Constant Value Description
3143
3144 Qt.Key_Escape 0x01000000
3145
3146 Qt.Key_Tab 0x01000001
3147
3148 Qt.Key_Backtab 0x01000002
3149
3150 Qt.Key_Backspace 0x01000003
3151
3152 Qt.Key_Return 0x01000004
3153
3154 Qt.Key_Enter 0x01000005 Typically located on the keypad.
3155
3156 Qt.Key_Insert 0x01000006
3157
3158 Qt.Key_Delete 0x01000007
3159
3160 Qt.Key_Pause 0x01000008 The Pause/Break key (Note: Not anything to do with pausing media)
3161
3162 Qt.Key_Print 0x01000009
3163
3164 Qt.Key_SysReq 0x0100000a
3165
3166 Qt.Key_Clear 0x0100000b
3167
3168 Qt.Key_Home 0x01000010
3169
3170 Qt.Key_End 0x01000011
3171
3172 Qt.Key_Left 0x01000012
3173
3174 Qt.Key_Up 0x01000013
3175
3176 Qt.Key_Right 0x01000014
3177
3178 Qt.Key_Down 0x01000015
3179
3180 Qt.Key_PageUp 0x01000016
3181
3182 Qt.Key_PageDown 0x01000017
3183
3184 Qt.Key_Shift 0x01000020
3185
3186 Qt.Key_Control 0x01000021 On Mac OS X, this corresponds to the Command keys.
3187
3188 Qt.Key_Meta 0x01000022 On Mac OS X, this corresponds to the Control keys. On Windows keyboards, this key is mapped to the Windows key.
3189
3190 Qt.Key_Alt 0x01000023
3191
3192 Qt.Key_AltGr 0x01001103 On Windows, when the KeyDown event for this key is sent, the Ctrl+Alt modifiers are also set.
3193
3194 Qt.Key_CapsLock 0x01000024
3195
3196 Qt.Key_NumLock 0x01000025
3197
3198 Qt.Key_ScrollLock 0x01000026
3199
3200 Qt.Key_F1 0x01000030
3201
3202 Qt.Key_F2 0x01000031
3203
3204 Qt.Key_F3 0x01000032
3205
3206 Qt.Key_F4 0x01000033
3207
3208 Qt.Key_F5 0x01000034
3209
3210 Qt.Key_F6 0x01000035
3211
3212 Qt.Key_F7 0x01000036
3213
3214 Qt.Key_F8 0x01000037
3215
3216 Qt.Key_F9 0x01000038
3217
3218 Qt.Key_F10 0x01000039
3219
3220 Qt.Key_F11 0x0100003a
3221
3222 Qt.Key_F12 0x0100003b
3223
3224 Qt.Key_F13 0x0100003c
3225
3226 Qt.Key_F14 0x0100003d
3227
3228 Qt.Key_F15 0x0100003e
3229
3230 Qt.Key_F16 0x0100003f
3231
3232 Qt.Key_F17 0x01000040
3233
3234 Qt.Key_F18 0x01000041
3235
3236 Qt.Key_F19 0x01000042
3237
3238 Qt.Key_F20 0x01000043
3239
3240 Qt.Key_F21 0x01000044
3241
3242 Qt.Key_F22 0x01000045
3243
3244 Qt.Key_F23 0x01000046
3245
3246 Qt.Key_F24 0x01000047
3247
3248 Qt.Key_F25 0x01000048
3249
3250 Qt.Key_F26 0x01000049
3251
3252 Qt.Key_F27 0x0100004a
3253
3254 Qt.Key_F28 0x0100004b
3255
3256 Qt.Key_F29 0x0100004c
3257
3258 Qt.Key_F30 0x0100004d
3259
3260 Qt.Key_F31 0x0100004e
3261
3262 Qt.Key_F32 0x0100004f
3263
3264 Qt.Key_F33 0x01000050
3265
3266 Qt.Key_F34 0x01000051
3267
3268 Qt.Key_F35 0x01000052
3269
3270 Qt.Key_Super_L 0x01000053
3271
3272 Qt.Key_Super_R 0x01000054
3273
3274 Qt.Key_Menu 0x01000055
3275
3276 Qt.Key_Hyper_L 0x01000056
3277
3278 Qt.Key_Hyper_R 0x01000057
3279
3280 Qt.Key_Help 0x01000058
3281
3282 Qt.Key_Direction_L 0x01000059
3283
3284 Qt.Key_Direction_R 0x01000060
3285
3286 Qt.Key_Space 0x20
3287
3288 Qt.Key_Any Key_Space
3289
3290 Qt.Key_Exclam 0x21
3291
3292 Qt.Key_QuoteDbl 0x22
3293
3294 Qt.Key_NumberSign 0x23
3295
3296 Qt.Key_Dollar 0x24
3297
3298 Qt.Key_Percent 0x25
3299
3300 Qt.Key_Ampersand 0x26
3301
3302 Qt.Key_Apostrophe 0x27
3303
3304 Qt.Key_ParenLeft 0x28
3305
3306 Qt.Key_ParenRight 0x29
3307
3308 Qt.Key_Asterisk 0x2a
3309
3310 Qt.Key_Plus 0x2b
3311
3312 Qt.Key_Comma 0x2c
3313
3314 Qt.Key_Minus 0x2d
3315
3316 Qt.Key_Period 0x2e
3317
3318 Qt.Key_Slash 0x2f
3319
3320 Qt.Key_0 0x30
3321
3322 Qt.Key_1 0x31
3323
3324 Qt.Key_2 0x32
3325
3326 Qt.Key_3 0x33
3327
3328 Qt.Key_4 0x34
3329
3330 Qt.Key_5 0x35
3331
3332 Qt.Key_6 0x36
3333
3334 Qt.Key_7 0x37
3335
3336 Qt.Key_8 0x38
3337
3338 Qt.Key_9 0x39
3339
3340 Qt.Key_Colon 0x3a
3341
3342 Qt.Key_Semicolon 0x3b
3343
3344 Qt.Key_Less 0x3c
3345
3346 Qt.Key_Equal 0x3d
3347
3348 Qt.Key_Greater 0x3e
3349
3350 Qt.Key_Question 0x3f
3351
3352 Qt.Key_At 0x40
3353
3354 Qt.Key_A 0x41
3355
3356 Qt.Key_B 0x42
3357
3358 Qt.Key_C 0x43
3359
3360 Qt.Key_D 0x44
3361
3362 Qt.Key_E 0x45
3363
3364 Qt.Key_F 0x46
3365
3366 Qt.Key_G 0x47
3367
3368 Qt.Key_H 0x48
3369
3370 Qt.Key_I 0x49
3371
3372 Qt.Key_J 0x4a
3373
3374 Qt.Key_K 0x4b
3375
3376 Qt.Key_L 0x4c
3377
3378 Qt.Key_M 0x4d
3379
3380 Qt.Key_N 0x4e
3381
3382 Qt.Key_O 0x4f
3383
3384 Qt.Key_P 0x50
3385
3386 Qt.Key_Q 0x51
3387
3388 Qt.Key_R 0x52
3389
3390 Qt.Key_S 0x53
3391
3392 Qt.Key_T 0x54
3393
3394 Qt.Key_U 0x55
3395
3396 Qt.Key_V 0x56
3397
3398 Qt.Key_W 0x57
3399
3400 Qt.Key_X 0x58
3401
3402 Qt.Key_Y 0x59
3403
3404 Qt.Key_Z 0x5a
3405
3406 Qt.Key_BracketLeft 0x5b
3407
3408 Qt.Key_Backslash 0x5c
3409
3410 Qt.Key_BracketRight 0x5d
3411
3412 Qt.Key_AsciiCircum 0x5e
3413
3414 Qt.Key_Underscore 0x5f
3415
3416 Qt.Key_QuoteLeft 0x60
3417
3418 Qt.Key_BraceLeft 0x7b
3419
3420 Qt.Key_Bar 0x7c
3421
3422 Qt.Key_BraceRight 0x7d
3423
3424 Qt.Key_AsciiTilde 0x7e
3425
3426 Qt.Key_nobreakspace 0x0a0
3427
3428 Qt.Key_exclamdown 0x0a1
3429
3430 Qt.Key_cent 0x0a2
3431
3432 Qt.Key_sterling 0x0a3
3433
3434 Qt.Key_currency 0x0a4
3435
3436 Qt.Key_yen 0x0a5
3437
3438 Qt.Key_brokenbar 0x0a6
3439
3440 Qt.Key_section 0x0a7
3441
3442 Qt.Key_diaeresis 0x0a8
3443
3444 Qt.Key_copyright 0x0a9
3445
3446 Qt.Key_ordfeminine 0x0aa
3447
3448 Qt.Key_guillemotleft 0x0ab
3449
3450 Qt.Key_notsign 0x0ac
3451
3452 Qt.Key_hyphen 0x0ad
3453
3454 Qt.Key_registered 0x0ae
3455
3456 Qt.Key_macron 0x0af
3457
3458 Qt.Key_degree 0x0b0
3459
3460 Qt.Key_plusminus 0x0b1
3461
3462 Qt.Key_twosuperior 0x0b2
3463
3464 Qt.Key_threesuperior 0x0b3
3465
3466 Qt.Key_acute 0x0b4
3467
3468 Qt.Key_mu 0x0b5
3469
3470 Qt.Key_paragraph 0x0b6
3471
3472 Qt.Key_periodcentered 0x0b7
3473
3474 Qt.Key_cedilla 0x0b8
3475
3476 Qt.Key_onesuperior 0x0b9
3477
3478 Qt.Key_masculine 0x0ba
3479
3480 Qt.Key_guillemotright 0x0bb
3481
3482 Qt.Key_onequarter 0x0bc
3483
3484 Qt.Key_onehalf 0x0bd
3485
3486 Qt.Key_threequarters 0x0be
3487
3488 Qt.Key_questiondown 0x0bf
3489
3490 Qt.Key_Agrave 0x0c0
3491
3492 Qt.Key_Aacute 0x0c1
3493
3494 Qt.Key_Acircumflex 0x0c2
3495
3496 Qt.Key_Atilde 0x0c3
3497
3498 Qt.Key_Adiaeresis 0x0c4
3499
3500 Qt.Key_Aring 0x0c5
3501
3502 Qt.Key_AE 0x0c6
3503
3504 Qt.Key_Ccedilla 0x0c7
3505
3506 Qt.Key_Egrave 0x0c8
3507
3508 Qt.Key_Eacute 0x0c9
3509
3510 Qt.Key_Ecircumflex 0x0ca
3511
3512 Qt.Key_Ediaeresis 0x0cb
3513
3514 Qt.Key_Igrave 0x0cc
3515
3516 Qt.Key_Iacute 0x0cd
3517
3518 Qt.Key_Icircumflex 0x0ce
3519
3520 Qt.Key_Idiaeresis 0x0cf
3521
3522 Qt.Key_ETH 0x0d0
3523
3524 Qt.Key_Ntilde 0x0d1
3525
3526 Qt.Key_Ograve 0x0d2
3527
3528 Qt.Key_Oacute 0x0d3
3529
3530 Qt.Key_Ocircumflex 0x0d4
3531
3532 Qt.Key_Otilde 0x0d5
3533
3534 Qt.Key_Odiaeresis 0x0d6
3535
3536 Qt.Key_multiply 0x0d7
3537
3538 Qt.Key_Ooblique 0x0d8
3539
3540 Qt.Key_Ugrave 0x0d9
3541
3542 Qt.Key_Uacute 0x0da
3543
3544 Qt.Key_Ucircumflex 0x0db
3545
3546 Qt.Key_Udiaeresis 0x0dc
3547
3548 Qt.Key_Yacute 0x0dd
3549
3550 Qt.Key_THORN 0x0de
3551
3552 Qt.Key_ssharp 0x0df
3553
3554 Qt.Key_division 0x0f7
3555
3556 Qt.Key_ydiaeresis 0x0ff
3557
3558 Qt.Key_Multi_key 0x01001120
3559
3560 Qt.Key_Codeinput 0x01001137
3561
3562 Qt.Key_SingleCandidate 0x0100113c
3563
3564 Qt.Key_MultipleCandidate 0x0100113d
3565
3566 Qt.Key_PreviousCandidate 0x0100113e
3567
3568 Qt.Key_Mode_switch 0x0100117e
3569
3570 Qt.Key_Kanji 0x01001121
3571
3572 Qt.Key_Muhenkan 0x01001122
3573
3574 Qt.Key_Henkan 0x01001123
3575
3576 Qt.Key_Romaji 0x01001124
3577
3578 Qt.Key_Hiragana 0x01001125
3579
3580 Qt.Key_Katakana 0x01001126
3581
3582 Qt.Key_Hiragana_Katakana 0x01001127
3583
3584 Qt.Key_Zenkaku 0x01001128
3585
3586 Qt.Key_Hankaku 0x01001129
3587
3588 Qt.Key_Zenkaku_Hankaku 0x0100112a
3589
3590 Qt.Key_Touroku 0x0100112b
3591
3592 Qt.Key_Massyo 0x0100112c
3593
3594 Qt.Key_Kana_Lock 0x0100112d
3595
3596 Qt.Key_Kana_Shift 0x0100112e
3597
3598 Qt.Key_Eisu_Shift 0x0100112f
3599
3600 Qt.Key_Eisu_toggle 0x01001130
3601
3602 Qt.Key_Hangul 0x01001131
3603
3604 Qt.Key_Hangul_Start 0x01001132
3605
3606 Qt.Key_Hangul_End 0x01001133
3607
3608 Qt.Key_Hangul_Hanja 0x01001134
3609
3610 Qt.Key_Hangul_Jamo 0x01001135
3611
3612 Qt.Key_Hangul_Romaja 0x01001136
3613
3614 Qt.Key_Hangul_Jeonja 0x01001138
3615
3616 Qt.Key_Hangul_Banja 0x01001139
3617
3618 Qt.Key_Hangul_PreHanja 0x0100113a
3619
3620 Qt.Key_Hangul_PostHanja 0x0100113b
3621
3622 Qt.Key_Hangul_Special 0x0100113f
3623
3624 Qt.Key_Dead_Grave 0x01001250
3625
3626 Qt.Key_Dead_Acute 0x01001251
3627
3628 Qt.Key_Dead_Circumflex 0x01001252
3629
3630 Qt.Key_Dead_Tilde 0x01001253
3631
3632 Qt.Key_Dead_Macron 0x01001254
3633
3634 Qt.Key_Dead_Breve 0x01001255
3635
3636 Qt.Key_Dead_Abovedot 0x01001256
3637
3638 Qt.Key_Dead_Diaeresis 0x01001257
3639
3640 Qt.Key_Dead_Abovering 0x01001258
3641
3642 Qt.Key_Dead_Doubleacute 0x01001259
3643
3644 Qt.Key_Dead_Caron 0x0100125a
3645
3646 Qt.Key_Dead_Cedilla 0x0100125b
3647
3648 Qt.Key_Dead_Ogonek 0x0100125c
3649
3650 Qt.Key_Dead_Iota 0x0100125d
3651
3652 Qt.Key_Dead_Voiced_Sound 0x0100125e
3653
3654 Qt.Key_Dead_Semivoiced_Sound 0x0100125f
3655
3656 Qt.Key_Dead_Belowdot 0x01001260
3657
3658 Qt.Key_Dead_Hook 0x01001261
3659
3660 Qt.Key_Dead_Horn 0x01001262
3661
3662 Qt.Key_Back 0x01000061
3663
3664 Qt.Key_Forward 0x01000062
3665
3666 Qt.Key_Stop 0x01000063
3667
3668 Qt.Key_Refresh 0x01000064
3669
3670 Qt.Key_VolumeDown 0x01000070
3671
3672 Qt.Key_VolumeMute 0x01000071
3673
3674 Qt.Key_VolumeUp 0x01000072
3675
3676 Qt.Key_BassBoost 0x01000073
3677
3678 Qt.Key_BassUp 0x01000074
3679
3680 Qt.Key_BassDown 0x01000075
3681
3682 Qt.Key_TrebleUp 0x01000076
3683
3684 Qt.Key_TrebleDown 0x01000077
3685
3686 Qt.Key_MediaPlay 0x01000080 A key setting the state of the media player to play
3687
3688 Qt.Key_MediaStop 0x01000081 A key setting the state of the media player to stop
3689
3690 Qt.Key_MediaPrevious 0x01000082
3691
3692 Qt.Key_MediaNext 0x01000083
3693
3694 Qt.Key_MediaRecord 0x01000084
3695
3696 Qt.Key_MediaPause 0x1000085 A key setting the state of the media player to pause (Note: not the pause/break key)
3697
3698 Qt.Key_MediaTogglePlayPause 0x1000086 A key to toggle the play/pause state in the media player (rather than setting an absolute state)
3699
3700 Qt.Key_HomePage 0x01000090
3701
3702 Qt.Key_Favorites 0x01000091
3703
3704 Qt.Key_Search 0x01000092
3705
3706 Qt.Key_Standby 0x01000093
3707
3708 Qt.Key_OpenUrl 0x01000094
3709
3710 Qt.Key_LaunchMail 0x010000a0
3711
3712 Qt.Key_LaunchMedia 0x010000a1
3713
3714 Qt.Key_Launch0 0x010000a2 On X11 this key is mapped to "My Computer" (XF86XK_MyComputer) key for legacy reasons.
3715
3716 Qt.Key_Launch1 0x010000a3 On X11 this key is mapped to "Calculator" (XF86XK_Calculator) key for legacy reasons.
3717
3718 Qt.Key_Launch2 0x010000a4 On X11 this key is mapped to XF86XK_Launch0 key for legacy reasons.
3719
3720 Qt.Key_Launch3 0x010000a5 On X11 this key is mapped to XF86XK_Launch1 key for legacy reasons.
3721
3722 Qt.Key_Launch4 0x010000a6 On X11 this key is mapped to XF86XK_Launch2 key for legacy reasons.
3723
3724 Qt.Key_Launch5 0x010000a7 On X11 this key is mapped to XF86XK_Launch3 key for legacy reasons.
3725
3726 Qt.Key_Launch6 0x010000a8 On X11 this key is mapped to XF86XK_Launch4 key for legacy reasons.
3727
3728 Qt.Key_Launch7 0x010000a9 On X11 this key is mapped to XF86XK_Launch5 key for legacy reasons.
3729
3730 Qt.Key_Launch8 0x010000aa On X11 this key is mapped to XF86XK_Launch6 key for legacy reasons.
3731
3732 Qt.Key_Launch9 0x010000ab On X11 this key is mapped to XF86XK_Launch7 key for legacy reasons.
3733
3734 Qt.Key_LaunchA 0x010000ac On X11 this key is mapped to XF86XK_Launch8 key for legacy reasons.
3735
3736 Qt.Key_LaunchB 0x010000ad On X11 this key is mapped to XF86XK_Launch9 key for legacy reasons.
3737
3738 Qt.Key_LaunchC 0x010000ae On X11 this key is mapped to XF86XK_LaunchA key for legacy reasons.
3739
3740 Qt.Key_LaunchD 0x010000af On X11 this key is mapped to XF86XK_LaunchB key for legacy reasons.
3741
3742 Qt.Key_LaunchE 0x010000b0 On X11 this key is mapped to XF86XK_LaunchC key for legacy reasons.
3743
3744 Qt.Key_LaunchF 0x010000b1 On X11 this key is mapped to XF86XK_LaunchD key for legacy reasons.
3745
3746 Qt.Key_LaunchG 0x0100010e On X11 this key is mapped to XF86XK_LaunchE key for legacy reasons.
3747
3748 Qt.Key_LaunchH 0x0100010f On X11 this key is mapped to XF86XK_LaunchF key for legacy reasons.
3749
3750 Qt.Key_MonBrightnessUp 0x010000b2
3751
3752 Qt.Key_MonBrightnessDown 0x010000b3
3753
3754 Qt.Key_KeyboardLightOnOff 0x010000b4
3755
3756 Qt.Key_KeyboardBrightnessUp 0x010000b5
3757
3758 Qt.Key_KeyboardBrightnessDown 0x010000b6
3759
3760 Qt.Key_PowerOff 0x010000b7
3761
3762 Qt.Key_WakeUp 0x010000b8
3763
3764 Qt.Key_Eject 0x010000b9
3765
3766 Qt.Key_ScreenSaver 0x010000ba
3767
3768 Qt.Key_WWW 0x010000bb
3769
3770 Qt.Key_Memo 0x010000bc
3771
3772 Qt.Key_LightBulb 0x010000bd
3773
3774 Qt.Key_Shop 0x010000be
3775
3776 Qt.Key_History 0x010000bf
3777
3778 Qt.Key_AddFavorite 0x010000c0
3779
3780 Qt.Key_HotLinks 0x010000c1
3781
3782 Qt.Key_BrightnessAdjust 0x010000c2
3783
3784 Qt.Key_Finance 0x010000c3
3785
3786 Qt.Key_Community 0x010000c4
3787
3788 Qt.Key_AudioRewind 0x010000c5
3789
3790 Qt.Key_BackForward 0x010000c6
3791
3792 Qt.Key_ApplicationLeft 0x010000c7
3793
3794 Qt.Key_ApplicationRight 0x010000c8
3795
3796 Qt.Key_Book 0x010000c9
3797
3798 Qt.Key_CD 0x010000ca
3799
3800 Qt.Key_Calculator 0x010000cb On X11 this key is not mapped for legacy reasons. Use Qt.Key_Launch1 instead.
3801
3802 Qt.Key_ToDoList 0x010000cc
3803
3804 Qt.Key_ClearGrab 0x010000cd
3805
3806 Qt.Key_Close 0x010000ce
3807
3808 Qt.Key_Copy 0x010000cf
3809
3810 Qt.Key_Cut 0x010000d0
3811
3812 Qt.Key_Display 0x010000d1
3813
3814 Qt.Key_DOS 0x010000d2
3815
3816 Qt.Key_Documents 0x010000d3
3817
3818 Qt.Key_Excel 0x010000d4
3819
3820 Qt.Key_Explorer 0x010000d5
3821
3822 Qt.Key_Game 0x010000d6
3823
3824 Qt.Key_Go 0x010000d7
3825
3826 Qt.Key_iTouch 0x010000d8
3827
3828 Qt.Key_LogOff 0x010000d9
3829
3830 Qt.Key_Market 0x010000da
3831
3832 Qt.Key_Meeting 0x010000db
3833
3834 Qt.Key_MenuKB 0x010000dc
3835
3836 Qt.Key_MenuPB 0x010000dd
3837
3838 Qt.Key_MySites 0x010000de
3839
3840 Qt.Key_News 0x010000df
3841
3842 Qt.Key_OfficeHome 0x010000e0
3843
3844 Qt.Key_Option 0x010000e1
3845
3846 Qt.Key_Paste 0x010000e2
3847
3848 Qt.Key_Phone 0x010000e3
3849
3850 Qt.Key_Calendar 0x010000e4
3851
3852 Qt.Key_Reply 0x010000e5
3853
3854 Qt.Key_Reload 0x010000e6
3855
3856 Qt.Key_RotateWindows 0x010000e7
3857
3858 Qt.Key_RotationPB 0x010000e8
3859
3860 Qt.Key_RotationKB 0x010000e9
3861
3862 Qt.Key_Save 0x010000ea
3863
3864 Qt.Key_Send 0x010000eb
3865
3866 Qt.Key_Spell 0x010000ec
3867
3868 Qt.Key_SplitScreen 0x010000ed
3869
3870 Qt.Key_Support 0x010000ee
3871
3872 Qt.Key_TaskPane 0x010000ef
3873
3874 Qt.Key_Terminal 0x010000f0
3875
3876 Qt.Key_Tools 0x010000f1
3877
3878 Qt.Key_Travel 0x010000f2
3879
3880 Qt.Key_Video 0x010000f3
3881
3882 Qt.Key_Word 0x010000f4
3883
3884 Qt.Key_Xfer 0x010000f5
3885
3886 Qt.Key_ZoomIn 0x010000f6
3887
3888 Qt.Key_ZoomOut 0x010000f7
3889
3890 Qt.Key_Away 0x010000f8
3891
3892 Qt.Key_Messenger 0x010000f9
3893
3894 Qt.Key_WebCam 0x010000fa
3895
3896 Qt.Key_MailForward 0x010000fb
3897
3898 Qt.Key_Pictures 0x010000fc
3899
3900 Qt.Key_Music 0x010000fd
3901
3902 Qt.Key_Battery 0x010000fe
3903
3904 Qt.Key_Bluetooth 0x010000ff
3905
3906 Qt.Key_WLAN 0x01000100
3907
3908 Qt.Key_UWB 0x01000101
3909
3910 Qt.Key_AudioForward 0x01000102
3911
3912 Qt.Key_AudioRepeat 0x01000103
3913
3914 Qt.Key_AudioRandomPlay 0x01000104
3915
3916 Qt.Key_Subtitle 0x01000105
3917
3918 Qt.Key_AudioCycleTrack 0x01000106
3919
3920 Qt.Key_Time 0x01000107
3921
3922 Qt.Key_Hibernate 0x01000108
3923
3924 Qt.Key_View 0x01000109
3925
3926 Qt.Key_TopMenu 0x0100010a
3927
3928 Qt.Key_PowerDown 0x0100010b
3929
3930 Qt.Key_Suspend 0x0100010c
3931
3932 Qt.Key_ContrastAdjust 0x0100010d
3933
3934 Qt.Key_MediaLast 0x0100ffff
3935
3936 Qt.Key_unknown 0x01ffffff
3937
3938 Qt.Key_Call 0x01100004 A key to answer or initiate a call (see Qt.Key_ToggleCallHangup for a key to toggle current call state)
3939
3940 Qt.Key_Camera 0x01100020 A key to activate the camera shutter
3941
3942 Qt.Key_CameraFocus 0x01100021 A key to focus the camera
3943
3944 Qt.Key_Context1 0x01100000
3945
3946 Qt.Key_Context2 0x01100001
3947
3948 Qt.Key_Context3 0x01100002
3949
3950 Qt.Key_Context4 0x01100003
3951
3952 Qt.Key_Flip 0x01100006
3953
3954 Qt.Key_Hangup 0x01100005 A key to end an ongoing call (see Qt.Key_ToggleCallHangup for a key to toggle current call state)
3955
3956 Qt.Key_No 0x01010002
3957
3958 Qt.Key_Select 0x01010000
3959
3960 Qt.Key_Yes 0x01010001
3961
3962 Qt.Key_ToggleCallHangup 0x01100007 A key to toggle the current call state (ie. either answer, or hangup) depending on current call state
3963
3964 Qt.Key_VoiceDial 0x01100008
3965
3966 Qt.Key_LastNumberRedial 0x01100009
3967
3968 Qt.Key_Execute 0x01020003
3969
3970 Qt.Key_Printer 0x01020002
3971
3972 Qt.Key_Play 0x01020005
3973
3974 Qt.Key_Sleep 0x01020004
3975
3976 Qt.Key_Zoom 0x01020006
3977
3978 Qt.Key_Cancel 0x01020001
3979 '''
3980