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