0

ウィザードの 2 ページ目にゲージを表示して更新するのに問題があります。100%になるまで表示されません。EVT_WIZARD_PAGE_CHANGEDページ上のオブジェクトが表示される前にイベントが処理されるようです。

以下のコードは、私がやろうとしていることの簡略化されたバージョンです。実行すると、fill_gauge メソッドが終了してゲージが 100% になるまで 2 ページ目がハングし、最終的に画面に表示されます。2番目のページに変更して動的に更新するとすぐにゲージを表示する方法のアイデアはありますか?

import time
import wx.wizard

class Wizard(wx.wizard.Wizard):
    def __init__(self, parent, title):
        wx.wizard.Wizard.__init__(self, parent, wx.ID_ANY, title )
        self.pages = []
        self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.on_page_changed)

    def add_page(self, page):
        """Add a WizardPage to the pages list"""
        self.pages.append(page)

    def chain_pages(self):
        i = 0
        while 1:
            if i == len(self.pages) - 1:
                break
            else:
                wx.wizard.WizardPageSimple_Chain(self.pages[i], self.pages[i + 1])
                i += 1

    def run(self):
        self.RunWizard(self.pages[0])

    def on_page_changed(self, evt):
        #if coming from self.pages[0]
        #and direction is forward
        if evt.GetDirection(): direction = 'forward'
        else:                  direction = 'backward'

        if evt.GetPage() is self.pages[1]\
        and direction == "forward":
            self.pages[1].fill_gauge()

class StartPage(wx.wizard.WizardPageSimple):

    def __init__(self, parent, title):
        wx.wizard.WizardPageSimple.__init__(self, parent)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.text = wx.StaticText(self, -1,
        "This is the First Page")
        #self.text.Wrap(parent.GetClientSizeTuple()[0])
        self.sizer.Add(self.text, 0, wx.ALIGN_CENTER|wx.ALL, 5)

class UpdatePage(wx.wizard.WizardPageSimple):
    def __init__(self, parent, title):
        wx.wizard.WizardPageSimple.__init__(self, parent)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.status = wx.StaticText(self, -1, "This is the Second Page")
        self.gauge = wx.Gauge(self, -1, name = "Guage")

        self.sizer.Add(self.status, 0, wx.ALIGN_CENTER|wx.ALL, 5)
        self.sizer.Add(self.gauge, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 10)
        self.SetSizer(self.sizer)

    def update(self, percent, status):
        self.status.SetLabel(status)
        self.gauge.SetValue(percent)
        #self.Refresh()

    def fill_gauge(self):
        x = 0
        while x <=100:
            self.update(x, "Gauge is at %d" % x)
            x += 10
            time.sleep(1)

if __name__ == '__main__':
    app = wx.App()
    wizard = Wizard(None, "Updater")
    wizard.add_page(StartPage(wizard, "Updater"))
    wizard.add_page(UpdatePage(wizard, "Updater"))
    wizard.chain_pages()
    wizard.run()
    wizard.Destroy()
    app.MainLoop()
4

1 に答える 1

1

ゲージを更新する方法が、GUI のイベント ループをブロックしています。ブロックしないように、wx.Timer を使用して更新を呼び出すことができます。変更されたコードの次の例を参照してください。

import time 
import wx.wizard


class Wizard(wx.wizard.Wizard):
    def __init__(self, parent, title):
        wx.wizard.Wizard.__init__(self, parent, wx.ID_ANY, title)
        self.pages = []
        self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.on_page_changed)

    def add_page(self, page):
        """Add a WizardPage to the pages list"""
        self.pages.append(page)

    def chain_pages(self):
        i = 0
        while 1:
            if i == len(self.pages) - 1:
                break
            else:
                wx.wizard.WizardPageSimple_Chain(self.pages[i],
                                                 self.pages[i + 1])
                i += 1

    def run(self):
        self.RunWizard(self.pages[0])

    def on_page_changed(self, evt):
        # if coming from self.pages[0]
        # and direction is forward
        if evt.GetDirection():
            direction = 'forward'
        else:
            direction = 'backward'

        if evt.GetPage() is self.pages[1]\
        and direction == "forward":
#             self.pages[1].fill_gauge()
            self.pages[1].timer.Start(1000)


class StartPage(wx.wizard.WizardPageSimple):

    def __init__(self, parent, title):
        wx.wizard.WizardPageSimple.__init__(self, parent)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.text = wx.StaticText(self, -1,
        "This is the First Page")
        # self.text.Wrap(parent.GetClientSizeTuple()[0])
        self.sizer.Add(self.text, 0, wx.ALIGN_CENTER | wx.ALL, 5)


class UpdatePage(wx.wizard.WizardPageSimple):
    def __init__(self, parent, title):
        wx.wizard.WizardPageSimple.__init__(self, parent)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.status = wx.StaticText(self, -1, "This is the Second Page")
        self.gauge = wx.Gauge(self, -1, name="Guage")

        self.sizer.Add(self.status, 0, wx.ALIGN_CENTER | wx.ALL, 5)
        self.sizer.Add(self.gauge, 0,
                       wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 10)
        self.SetSizer(self.sizer)

        self.gauge_pos = 0  # Added
        self.timer = wx.Timer(self)  # Added
        self.Bind(wx.EVT_TIMER, self.on_gauge_timer)  # Added

    def update(self, percent, status):
        self.status.SetLabel(status)
        self.gauge.SetValue(percent)
        # self.Refresh()

#     def fill_gauge(self):
#         x = 0
#         while x <= 100:
#             self.update(x, "Gauge is at %d" % x)
#             x += 10
#             time.sleep(1)

    def on_gauge_timer(self, event):  # Added method
        if self.gauge_pos < 100:
            self.gauge_pos += 10
            self.update(self.gauge_pos, "Gauge is at %d" % self.gauge_pos)
        else:
            self.timer.Stop()
            self.gauge_pos = 0


if __name__ == '__main__':
    app = wx.App()
    wizard = Wizard(None, "Updater")
    wizard.add_page(StartPage(wizard, "Updater"))
    wizard.add_page(UpdatePage(wizard, "Updater"))
    wizard.chain_pages()
    wizard.run()
    wizard.Destroy()
    app.MainLoop()

注:ページに戻った場合にタイマーを停止してゲージをリセットするには、より良いコードを追加する必要がありますが、基本的に機能するようにしただけです。

于 2013-09-01T11:47:43.533 に答える