Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

threadedgui.py 6.1KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. # Demo of using just windows, without documents and views.
  2. # Also demo of a GUI thread, pretty much direct from the MFC C++ sample MTMDI.
  3. import timer
  4. import win32api
  5. import win32con
  6. import win32ui
  7. from pywin.mfc import docview, thread, window
  8. from pywin.mfc.thread import WinThread
  9. WM_USER_PREPARE_TO_CLOSE = win32con.WM_USER + 32
  10. # font is a dictionary in which the following elements matter:
  11. # (the best matching font to supplied parameters is returned)
  12. # name string name of the font as known by Windows
  13. # size point size of font in logical units
  14. # weight weight of font (win32con.FW_NORMAL, win32con.FW_BOLD)
  15. # italic boolean; true if set to anything but None
  16. # underline boolean; true if set to anything but None
  17. # This window is a child window of a frame. It is not the frame window itself.
  18. class FontWindow(window.Wnd):
  19. def __init__(self, text="Python Rules!"):
  20. window.Wnd.__init__(self)
  21. self.text = text
  22. self.index = 0
  23. self.incr = 1
  24. self.width = self.height = 0
  25. self.ChangeAttributes()
  26. # set up message handlers
  27. def Create(self, title, style, rect, parent):
  28. classStyle = win32con.CS_HREDRAW | win32con.CS_VREDRAW
  29. className = win32ui.RegisterWndClass(
  30. classStyle, 0, win32con.COLOR_WINDOW + 1, 0
  31. )
  32. self._obj_ = win32ui.CreateWnd()
  33. self._obj_.AttachObject(self)
  34. self._obj_.CreateWindow(
  35. className, title, style, rect, parent, win32ui.AFX_IDW_PANE_FIRST
  36. )
  37. self.HookMessage(self.OnSize, win32con.WM_SIZE)
  38. self.HookMessage(self.OnPrepareToClose, WM_USER_PREPARE_TO_CLOSE)
  39. self.HookMessage(self.OnDestroy, win32con.WM_DESTROY)
  40. self.timerid = timer.set_timer(100, self.OnTimer)
  41. self.InvalidateRect()
  42. def OnDestroy(self, msg):
  43. timer.kill_timer(self.timerid)
  44. def OnTimer(self, id, timeVal):
  45. self.index = self.index + self.incr
  46. if self.index > len(self.text):
  47. self.incr = -1
  48. self.index = len(self.text)
  49. elif self.index < 0:
  50. self.incr = 1
  51. self.index = 0
  52. self.InvalidateRect()
  53. def OnPaint(self):
  54. # print "Paint message from thread", win32api.GetCurrentThreadId()
  55. dc, paintStruct = self.BeginPaint()
  56. self.OnPrepareDC(dc, None)
  57. if self.width == 0 and self.height == 0:
  58. left, top, right, bottom = self.GetClientRect()
  59. self.width = right - left
  60. self.height = bottom - top
  61. x, y = self.width // 2, self.height // 2
  62. dc.TextOut(x, y, self.text[: self.index])
  63. self.EndPaint(paintStruct)
  64. def ChangeAttributes(self):
  65. font_spec = {"name": "Arial", "height": 42}
  66. self.font = win32ui.CreateFont(font_spec)
  67. def OnPrepareToClose(self, params):
  68. self.DestroyWindow()
  69. def OnSize(self, params):
  70. lParam = params[3]
  71. self.width = win32api.LOWORD(lParam)
  72. self.height = win32api.HIWORD(lParam)
  73. def OnPrepareDC(self, dc, printinfo):
  74. # Set up the DC for forthcoming OnDraw call
  75. dc.SetTextColor(win32api.RGB(0, 0, 255))
  76. dc.SetBkColor(win32api.GetSysColor(win32con.COLOR_WINDOW))
  77. dc.SelectObject(self.font)
  78. dc.SetTextAlign(win32con.TA_CENTER | win32con.TA_BASELINE)
  79. class FontFrame(window.MDIChildWnd):
  80. def __init__(self):
  81. pass # Dont call base class doc/view version...
  82. def Create(self, title, rect=None, parent=None):
  83. style = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_OVERLAPPEDWINDOW
  84. self._obj_ = win32ui.CreateMDIChild()
  85. self._obj_.AttachObject(self)
  86. self._obj_.CreateWindow(None, title, style, rect, parent)
  87. rect = self.GetClientRect()
  88. rect = (0, 0, rect[2] - rect[0], rect[3] - rect[1])
  89. self.child = FontWindow("Not threaded")
  90. self.child.Create(
  91. "FontDemo", win32con.WS_CHILD | win32con.WS_VISIBLE, rect, self
  92. )
  93. class TestThread(WinThread):
  94. def __init__(self, parentWindow):
  95. self.parentWindow = parentWindow
  96. self.child = None
  97. WinThread.__init__(self)
  98. def InitInstance(self):
  99. rect = self.parentWindow.GetClientRect()
  100. rect = (0, 0, rect[2] - rect[0], rect[3] - rect[1])
  101. self.child = FontWindow()
  102. self.child.Create(
  103. "FontDemo", win32con.WS_CHILD | win32con.WS_VISIBLE, rect, self.parentWindow
  104. )
  105. self.SetMainFrame(self.child)
  106. return WinThread.InitInstance(self)
  107. def ExitInstance(self):
  108. return 0
  109. class ThreadedFontFrame(window.MDIChildWnd):
  110. def __init__(self):
  111. pass # Dont call base class doc/view version...
  112. self.thread = None
  113. def Create(self, title, rect=None, parent=None):
  114. style = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_OVERLAPPEDWINDOW
  115. self._obj_ = win32ui.CreateMDIChild()
  116. self._obj_.CreateWindow(None, title, style, rect, parent)
  117. self._obj_.HookMessage(self.OnDestroy, win32con.WM_DESTROY)
  118. self._obj_.HookMessage(self.OnSize, win32con.WM_SIZE)
  119. self.thread = TestThread(self)
  120. self.thread.CreateThread()
  121. def OnSize(self, msg):
  122. pass
  123. def OnDestroy(self, msg):
  124. win32ui.OutputDebugString("OnDestroy\n")
  125. if self.thread and self.thread.child:
  126. child = self.thread.child
  127. child.SendMessage(WM_USER_PREPARE_TO_CLOSE, 0, 0)
  128. win32ui.OutputDebugString("Destroyed\n")
  129. def Demo():
  130. f = FontFrame()
  131. f.Create("Font Demo")
  132. def ThreadedDemo():
  133. rect = win32ui.GetMainFrame().GetMDIClient().GetClientRect()
  134. rect = rect[0], int(rect[3] * 3 / 4), int(rect[2] / 4), rect[3]
  135. incr = rect[2]
  136. for i in range(4):
  137. if i == 0:
  138. f = FontFrame()
  139. title = "Not threaded"
  140. else:
  141. f = ThreadedFontFrame()
  142. title = "Threaded GUI Demo"
  143. f.Create(title, rect)
  144. rect = rect[0] + incr, rect[1], rect[2] + incr, rect[3]
  145. # Givem a chance to start
  146. win32api.Sleep(100)
  147. win32ui.PumpWaitingMessages()
  148. if __name__ == "__main__":
  149. import demoutils
  150. if demoutils.NeedGoodGUI():
  151. ThreadedDemo()
  152. # Demo()