Как запустить код, только когда я нажимаю на конструктор button..python/wxpython/boa
Я разрабатываю графический интерфейс с помощью wxPython (Boa Constructor IDE). Мой графический интерфейс имеет следующее:
- Богатый текстовый контроль
- Кнопка Пуск
- Кнопка Стоп
Мое требование состоит в том, чтобы при нажатии кнопки 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()
2 ответа
Резюме
В общем, это приемлемый способ сделать это в wxPython, и он идет прямо из документации.
Создайте новое событие "data".
Заставьте ваш контроллер прослушивать события "data"
Давайте нажмем кнопку "Пуск", чтобы запустить поток, который увеличивает счетчик и отправляет событие "данные" в ваше окно со значением счетчика.
После получения события, добавьте значение к вашему
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()
Для чего-то столь же простого, как это, я бы просто использовал wx.Timer вместо того, чтобы возиться с потоками. как в этом уроке.
Если вы действительно хотите использовать потоки, вам, вероятно, захочется прочитать одно из следующего: