2

いくつかのコンポーネントと 2 つの wx.Frame オブジェクト F1 および F2 を使用して GUI を設計しています。F1 はメイン フレームで、F2 はセカンダリ フレームです。ユーザーがこの 2 つのフレームを 1 つのフレームに取り付け、必要に応じて再び 2 つのフレームに取り外すことができるメカニズムが必要です。

F1 と F2 に、それぞれパネル P1 と P2 が含まれているとします。デタッチすると、ユーザーは各フレームを個別に移動およびサイズ変更できる必要があり、F1 を閉じると GUI 全体が閉じます。取り付けられると、F1 は P1 と P2 の両方を垂直に含み、F2 は消えて F1 の一部になるように見えます。P1 と P2 の間で渡される多くの配線とイベントとメッセージがあり、接続モードと接続解除モードの両方で動作するはずです。

いくつかの最新の GUI でこの効果を見たことがありますが、これを実行するための適切なテクニックをオンラインで見つけることができませんでした。これを行う適切な方法は何ですか?

ありがとう

4

3 に答える 3

2

pubsub モジュールを使用して、これに対する解決策を思いつきました。以下は、それがどのように行われるかを示すために私が書いた小さな例です。

import wx
import gettext
from wx.lib.pubsub import pub

class SubFramePanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY)
        self.attachDetachButton = wx.Button(self, wx.ID_ANY, _("Attach"))
        self.sayHelloButton = wx.Button(self, wx.ID_ANY, _("Say Hello"))        
        subPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
        subPanelSizer.Add(self.attachDetachButton, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
        subPanelSizer.Add(self.sayHelloButton, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 0)
        self.SetSizer(subPanelSizer)
        self.attachDetachButton.Bind(wx.EVT_BUTTON, self.OnAttachDetachButton)
        self.sayHelloButton.Bind(wx.EVT_BUTTON, self.OnSayHelloButton)

    def OnAttachDetachButton(self, event):
        if self.attachDetachButton.GetLabel() == "Attach":
            self.attachDetachButton.SetLabel("Detach")
            pub.sendMessage("show.mainframe.OnAttach", data=self)
        else:
            self.attachDetachButton.SetLabel("Attach")
            pub.sendMessage("show.mainframe.OnDetach", data=self)
        event.Skip()

    def OnSayHelloButton(self, event):
        pub.sendMessage("show.mainframe.addText", data="Say Hello\n")
        event.Skip()


class SubFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        if kwds.has_key("panel"):
            self.panel = kwds["panel"]
            del kwds["panel"]
        else:
            self.panel = None

        wx.Frame.__init__(self, *args, **kwds)

        if self.panel is None:
            self.panel = SubFramePanel(self)
        else:
            self.panel.Reparent(self)

        self.SetTitle(_("Sub Frame"))
        self.SetSize((291, 93))

        subFrameSizer = wx.BoxSizer(wx.VERTICAL)

        subFrameSizer.Add(self.panel, 1, wx.EXPAND | wx.LEFT, 5)
        self.SetSizer(subFrameSizer)
        self.Layout()
        pub.subscribe(self.OnClose, "show.subframe.OnClose")

    def OnClose(self, data=None):
        self.Close()


# end of class SubFrame

class MainFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.text_ctrl_1 = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE)

        pub.subscribe(self.OnAddText, "show.mainframe.addText")
        pub.subscribe(self.OnAttach, "show.mainframe.OnAttach")
        pub.subscribe(self.OnDetach, "show.mainframe.OnDetach")

        self.SetTitle(_("Main Frame"))
        self.SetSize((492, 271))
        self.mainFrameSizer = wx.BoxSizer(wx.VERTICAL)
        self.mainFrameSizer.Add(self.text_ctrl_1, 1, wx.ALL | wx.EXPAND, 5)
        self.SetSizer(self.mainFrameSizer)
        self.Layout()

    def OnAddText(self, data):
        self.text_ctrl_1.WriteText(data)

    def OnAttach(self, data):
        self.mainFrameSizer.Add(data, 0, wx.ALL | wx.EXPAND, 5)
        data.Reparent(self)
        self.Layout()
        pub.sendMessage("show.subframe.OnClose")

    def OnDetach(self, data):
        subFrame = SubFrame(self, wx.ID_ANY, "", panel=data)
        self.mainFrameSizer.Remove(data)
        self.Layout()
        subFrame.Show()

class MyApp(wx.App):
    def OnInit(self):
        mainFrame = MainFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(mainFrame)
        mainFrame.Show()
        subFrame = SubFrame(mainFrame, wx.ID_ANY, "")
        subFrame.Show()
        return 1

if __name__ == "__main__":
    gettext.install("app")
    app = MyApp(0)
    app.MainLoop()
于 2013-05-16T18:36:24.937 に答える
0

wx でその場でwxPanelaから別の a に移動できるかどうかはわかりません。wxFrame

主な理由は、パネルがその親に依存しており、その場で変更できないことです。

本当にやりたい場合は、他のフレームにパネルをコピーして作成し、前のパネルとフレームを削除する (または非表示にする) 必要があります。

組み込みのコピーはありませんが、元のパネルのコンテンツを取得して別のパネルにコピーする方法を見つけることができます。

于 2013-05-14T07:18:32.250 に答える
0

wxPython には AUI というライブラリがあります。フレームからパネルを取り外すメカニズムを提供します。次のリンクには、他の情報とともに例があります。

http://wiki.wxpython.org/AuiNotebook%20(AGW)

于 2014-05-30T18:19:02.740 に答える