wxpython: приостановить код до тех пор, пока открыт второй кадр

#python #pycharm #event-handling #wxpython #frame

#python #pycharm #обработка событий #wxpython #кадр

Вопрос:

Я в значительной степени новичок в Python и только недавно начал работать с wxpython, и теперь у меня следующий вопрос:

Я пишу приложение, в котором открыто одно окно, и, нажав кнопку, пользователь открывает второе окно, где он должен ввести свое имя и нажать другую кнопку. Моя проблема в том, что я не знаю, как приостановить «код события», который выполняется нажатием Button1, пока пользователь не завершит свои действия во втором окне.

Есть ли способ приостановить код в OnButton1 (после строки secondframe.Show() , пока пользователь не введет свое имя во втором кадре и не нажмет на OnButton2?

По сути, моя цель состоит в том, чтобы сначала печаталось имя пользователя, и только после этого печатается Done

 class MainFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)

        self.panel = wx.Panel(self)
        self.Button1 = wx.Button(self.panel, label='Button 1', pos=(20, 10), size=(90, 25))

        #Set event handlers
        self.Button1.Bind(wx.EVT_BUTTON, self.OnButton1)

    def OnButton1(self, e):
        secondframe = SecondFrame(None)
        secondframe.Show()
        print("Done")



class SecondFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)

        self.panel = wx.Panel(self)
        self.Button2 = wx.Button(self.panel, label='Button 2', pos=(50, 20), size=(90, 25))
        self.NameBox = wx.TextCtrl(self.panel, value="Type Your Name", pos=(50, 60), size=(200, -1))


        #Set event handlers
        self.Button2.Bind(wx.EVT_BUTTON, self.OnButton2)

    def OnButton2(self, e):
        Name = self.NameBox.GetValue()
        print(Name)


app = wx.App(False)
frame = MainFrame(None)
frame.Show()
app.MainLoop()

 

Комментарии:

1. Общие классы и функции диалогового окна инкапсулируют часто необходимые требования к диалоговому окну. Все они являются «модальными», перехватывая поток управления до тех пор, пока пользователь не закроет диалоговое окно, чтобы упростить их использование в приложении.

Ответ №1:

Я не знаю способа фактически заблокировать код там. (Кроме того, блокировка, вообще говоря, никогда не является хорошей идеей.)
Но вы можете получить такое же поведение, как это:

  • Когда вы открываете второе окно, в первом окне вы вызываете self.Disable()
  • При создании второго окна вы также передаете ему ссылку на первое окно (т.Е. secondframe = SecondFrame(None, self) ), настраиваете конструктор ( def __init__(self, parent, main): ) и сохраняете это в переменной there ( self.mainFrame = main ) .
  • Вы добавляете метод в мэйнфрейм, например reenable(self)
  • там вы вызываете self.Enable()
  • Когда вы закончите со вторым кадром, вы можете просто вызвать self.mainFrame.reenable()

В целом, это сделало бы что-то вроде:

 class MainFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)

        self.panel = wx.Panel(self)
        self.Button1 = wx.Button(self.panel, label='Button 1', pos=(20, 10), size=(90, 25))

        #Set event handlers
        self.Button1.Bind(wx.EVT_BUTTON, self.OnButton1)

    def OnButton1(self, e):
        secondframe = SecondFrame(None, self)
        self.Disable()
        secondframe.Show()

    def reenable(self):
        self.Enable()
        print("done")



class SecondFrame(wx.Frame):
    def __init__(self, parent, main):
        wx.Frame.__init__(self, parent)
        self.mainFrame = main

        self.panel = wx.Panel(self)
        self.Button2 = wx.Button(self.panel, label='Button 2', pos=(50, 20), size=(90, 25))
        self.NameBox = wx.TextCtrl(self.panel, value="Type Your Name", pos=(50, 60), size=(200, -1))


        #Set event handlers
        self.Button2.Bind(wx.EVT_BUTTON, self.OnButton2)

    def OnButton2(self, e):
        Name = self.NameBox.GetValue()
        print(Name)
        self.mainFrame.reenable()


app = wx.App(False)
frame = MainFrame(None)
frame.Show()
app.MainLoop()
 

Комментарии:

1. выглядит хорошо! У меня была похожая идея, но я не был уверен, как ее выполнить, спасибо!

2. С удовольствием. На самом деле вы, вероятно, захотите повторно включить первое окно при закрытии, а не при нажатии кнопки. Другим способом его реализации было бы сделать второе окно пользовательским диалогом и показать его модальным — это может быть проще, если у него короткое время жизни, но для более длительного времени жизни фрейм, вероятно, является правильным вызовом.