0

我正在使用 wxPython(Boa Constructor IDE)开发一个 GUI。我的 GUI 有以下内容:

  1. 富文本控件
  2. 开始按钮
  3. 停止按钮

我的要求是当我按下 START 按钮时,数字(1、2、3 等)应该开始在文本控件中打印;当我按下停止按钮时它应该停止。代码和图形用户界面如图所示。我需要进行哪些更改才能满足我的要求?

外貌:

在此处输入图像描述

代码:

import wx
import wx.richtext

def create(parent):
    return Frame3(parent)

[wxID_FRAME3, wxID_FRAME3BUTTON1, wxID_FRAME3BUTTON2, wxID_FRAME3PANEL1, 
 wxID_FRAME3RICHTEXTCTRL1, 
] = [wx.NewId() for _init_ctrls in range(5)]

class Frame3(wx.Frame):
    def _init_ctrls(self, prnt):
        # generated method, don't edit
        wx.Frame.__init__(self, id=wxID_FRAME3, name='', parent=prnt,
              pos=wx.Point(579, 234), size=wx.Size(414, 492),
              style=wx.DEFAULT_FRAME_STYLE, title='Frame3')
        self.SetClientSize(wx.Size(406, 458))

        self.panel1 = wx.Panel(id=wxID_FRAME3PANEL1, name='panel1', parent=self,
              pos=wx.Point(0, 0), size=wx.Size(406, 458),
              style=wx.TAB_TRAVERSAL)

        self.richTextCtrl1 = wx.richtext.RichTextCtrl(id=wxID_FRAME3RICHTEXTCTRL1,
              parent=self.panel1, pos=wx.Point(96, 96), size=wx.Size(200, 100),
              style=wx.richtext.RE_MULTILINE, value=u'')
        self.richTextCtrl1.SetLabel(u'richText')

        self.button2 = wx.Button(id=wxID_FRAME3BUTTON2, label=u'STOP',
              name='button2', parent=self.panel1, pos=wx.Point(256, 280),
              size=wx.Size(75, 23), style=0)
        self.button2.Bind(wx.EVT_BUTTON, self.OnButton2Button,
              id=wxID_FRAME3BUTTON2)

        self.button1 = wx.Button(id=wxID_FRAME3BUTTON1, label=u'START',
              name='button1', parent=self.panel1, pos=wx.Point(88, 280),
              size=wx.Size(75, 23), style=0)
        self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,
              id=wxID_FRAME3BUTTON1)

    def __init__(self, parent):
        self._init_ctrls(parent)

    def OnButton1Button(self, event):  #START BUTTON
        event.Skip()

    def OnButton2Button(self, event):  #STOP BUTTON
        event.Skip()


if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = create(None)
    frame.Show()

    app.MainLoop()
4

2 回答 2

2

概括

一般来说,这是在 wxPython 中公认的做法,直接来自文档

  1. 创建一个新的“数据”事件。

  2. 让你的控制器监听“数据”事件

  3. 让按下“开始”按钮启动一个线程,该线程增加一个计数器并向您的窗口发送一个带有计数器值的“数据”事件。

  4. 收到事件后,将价值添加到您的RichTextCtrl

例子

这是一个例子。特别注意使用Connect()监听传入的值事件。

import wx
import wx.richtext
import threading
import time


EVT_ID_VALUE = wx.NewId()

class DataEvent(wx.PyEvent):
  def __init__(self, data):
    wx.PyEvent.__init__(self)
    self.SetEventType(EVT_ID_VALUE)
    self.data=data


class Frame3(wx.Frame):
  def __init__(self, parent, title):
    self.counter = 0
    self.worker = None

    wx.Frame.__init__(
      self, name='', 
      parent=parent,
      pos=wx.Point(579, 234), 
      size=wx.Size(414, 492),
      style=wx.DEFAULT_FRAME_STYLE, title='Frame3'
    )
    self.panel1 = wx.Panel(
      name='panel1', 
      parent=self,
      pos=wx.Point(0, 0), 
      size=wx.Size(406, 458),
      style=wx.TAB_TRAVERSAL
    )
    self.richTextCtrl1 = wx.richtext.RichTextCtrl(
      parent=self.panel1, 
      pos=wx.Point(96, 96), 
      size=wx.Size(200, 100),
      style=wx.richtext.RE_MULTILINE, 
      value=u''
    )
    self.richTextCtrl1.SetLabel(u'richText')
    self.richTextCtrl1.SetScrollbars(20,20,50,50)
    self.button2 = wx.Button(
      label=u'STOP',
      name='button2', 
      parent=self.panel1, 
      pos=wx.Point(256, 280),
      size=wx.Size(75, 23), 
      style=0
    )
    self.button2.Bind(
      wx.EVT_BUTTON, 
      self.OnStop
    )
    self.button1 = wx.Button(
      label=u'START',
      name='button1', 
      parent=self.panel1, 
      pos=wx.Point(88, 280),
      size=wx.Size(75, 23), 
      style=0
    )
    self.button1.Bind(
      wx.EVT_BUTTON, 
      self.OnStart
    )
    self.Connect(-1, -1, EVT_ID_VALUE, self.OnValue )

  def OnValue(self, event):
    self.richTextCtrl1.AppendText("%d\n"%event.data)
    
  
  def OnStart(self, event):  #START BUTTON
    self.richTextCtrl1.AppendText("START\n")
    if not self.worker:
      self.worker = WorkerThread(self)
      self.worker.start() 

  def OnStop(self, event):  #STOP BUTTON
    self.richTextCtrl1.AppendText("STOP\n")
    if self.worker:
      self.worker.stop() 


class WorkerThread(threading.Thread):
  def __init__(self, notify_window):
    threading.Thread.__init__(self)
    self.counter = 0
    self._notify_window = notify_window
    self.abort = False 

  def run(self):
    while not self.abort:
      self.counter += 1
      wx.PostEvent(self._notify_window, DataEvent(self.counter))
      time.sleep(1)

  def stop(self):
      self.abort = True



if __name__ == '__main__':
    app = wx.App()
    frame = Frame3(None, "My Hello App")
    frame.Show(True)
    app.MainLoop()
于 2012-05-01T12:01:54.253 回答
1

对于像这样简单的事情,我只会使用 wx.Timer 而不是搞乱线程。就像在本教程中一样。

如果您真的想使用线程,那么您可能需要阅读以下内容之一:

于 2012-05-01T14:49:25.930 回答