2013-05-10 2 views
1

Я проектирую графический интерфейс с несколькими компонентами и двумя объектами wx.Frame F1 и F2. F1 - основной кадр, а F2 - вторичный кадр. Я хотел бы иметь механизм, поэтому пользователь может прикрепить эти два кадра в один кадр, а также при необходимости отделить их на два кадра.Вставить/Снять два кадра в wxpython

Предположим, что F1 и F2 содержат панели P1 и P2 соответственно. При отсоединении использование должно иметь возможность перемещать и изменять размер каждого кадра независимо, а закрытие F1 закрывает весь графический интерфейс. При прикреплении F1 будет содержать как P1, так и P2 вертикально, а F2, похоже, исчезнет и станет частью F1. Существует много проводки и событий и сообщений, передаваемых между P1 и P2, которые должны работать как в подключенном, так и в отключенном режимах.

Я видел этот эффект в некоторых современных графических интерфейсах, но я не смог найти подходящую технику в Интернете, чтобы выполнить это. Каков правильный способ сделать это?

Благодаря

ответ

0

Существует библиотека в WxPython называется AUI. Он обеспечивает механизм отсоединения панели от кадра. Следующая ссылка имеет пример наряду с некоторой другой информацией:

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

0

Я не уверен, что вы можете переместить wxPanel из wxFrame в другой на лету на Wx.

Основная причина в том, что панель зависит от ее родителя, и вы не можете изменить ее на лету.

Теперь, если вы действительно хотите это сделать, вам придется создать копию панели в другом фрейме и удалить предыдущую панель и фрейм (или просто скрыть их).

Нет встроенной копии, но вы можете найти способ получить содержимое исходной панели и скопировать ее на другой.

1

Я придумал решение для этого, используя модуль 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()