Рубрики
Без рубрики

WXPYPHON: обеспечение только одного экземпляра на кадр

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

На днях я наткнулся на интересную Stackoverflow вопрос Там, где парень пытался выяснить, как открыть подкадж только один раз. По сути, он хотел один экземпляр подкадров (и других подзам). После немного копаться в Google, я нашел старый нить Из группы Google Google, которая имела интересный подход к тому, что нужно было.

В основном требуется немного мета-программирования, но это было весело малое упражнение, которое я думал, что мои читатели найдут интересно. Вот код:

import wx

########################################################################
class MyPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)


########################################################################
class SingleInstanceFrame(wx.Frame):
    """"""

    instance = None
    init = 0

    #----------------------------------------------------------------------
    def __new__(self, *args, **kwargs):
        """"""
        if self.instance is None:
            self.instance = wx.Frame.__new__(self)
        elif isinstance(self.instance, wx._core._wxPyDeadObject):
            self.instance = wx.Frame.__new__(self)
        return self.instance

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        print id(self)
        if self.init:
            return
        self.init = 1

        wx.Frame.__init__(self, None, title="Single Instance Frame")
        panel = MyPanel(self)
        self.Show()


########################################################################
class MainFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Main Frame")
        panel = MyPanel(self)
        btn = wx.Button(panel, label="Open Frame")
        btn.Bind(wx.EVT_BUTTON, self.open_frame)
        self.Show()

    #----------------------------------------------------------------------
    def open_frame(self, event):
        frame = SingleInstanceFrame()

if __name__ == '__main__':
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

Мясо этого кода в Одноинациональный секрет класс, специально в __new__ метод. Здесь мы проверяем, если переменная Self.instance устанавливается ни на что. Если это так, мы создаем новый экземпляр. Мы также создадим новый экземпляр, если пользователь закрывает кадр, что заставит его стать wxpydeadobject Отказ Это то, для чего является вторая часть оператора IF. Он проверяет, был ли удален экземпляра, и если у него есть, он создает новый экземпляр.

Вы также заметите, что у нас есть переменная под названием Self.init Отказ Это используется для проверки, если экземпляр уже инициализирован. Если это так, __init__ просто вернутся вместо того, чтобы повторно создать все.

wxpython 4/phoenix

В Wxpython 4/Phoenix нет wx._core._wxpydeadobject Таким образом, мы должны немного изменить наш код, чтобы он работал в новых версиях Wxpython. Вот как:

import wx


class MyPanel(wx.Panel):
    """"""

    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)


class SingleInstanceFrame(wx.Frame):
    """"""

    instance = None
    init = 0

    def __new__(self, *args, **kwargs):
        """"""
        if self.instance is None:
            self.instance = wx.Frame.__new__(self)
        elif not self.instance:
            self.instance = wx.Frame.__new__(self)

        return self.instance

    def __init__(self):
        """Constructor"""
        print(id(self))
        if self.init:
            return
        self.init = 1

        wx.Frame.__init__(self, None, title="Single Instance Frame")
        panel = MyPanel(self)
        self.Show()


class MainFrame(wx.Frame):
    """"""

    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Main Frame")
        panel = MyPanel(self)
        btn = wx.Button(panel, label="Open Frame")
        btn.Bind(wx.EVT_BUTTON, self.open_frame)
        self.Show()

    def open_frame(self, event):
        frame = SingleInstanceFrame()


if __name__ == '__main__':
    print wx.version()
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

Вы отметите, что только разница находится в __new__ Метод, где мы немного изменили условные операторы.

Я надеюсь, что вы нашли этот учебник полезным. Весело и счастливое кодирование!

Связанное чтение

Один пример работает WX.SingleInStanceChecker || документация