wxPython: отображение нескольких виджетов в одном кадре
-
05-07-2019 - |
Вопрос
Я хотел бы иметь возможность отображать Notebook
и виджеты TxtCtrl
wx в одном кадре. Ниже приведен пример, адаптированный из wxpython wiki; Можно ли изменить их макет (возможно, с помощью чего-то вроде wx.SplitterWindow
), чтобы отобразить текстовое поле под Notebook
в том же фрейме?
import wx
import wx.lib.sheet as sheet
class MySheet(sheet.CSheet):
def __init__(self, parent):
sheet.CSheet.__init__(self, parent)
self.SetLabelBackgroundColour('#CCFF66')
self.SetNumberRows(50)
self.SetNumberCols(50)
class Notebook(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 600))
menubar = wx.MenuBar()
file = wx.Menu()
file.Append(101, 'Quit', '' )
menubar.Append(file, "&File")
self.SetMenuBar(menubar)
wx.EVT_MENU(self, 101, self.OnQuit)
nb = wx.Notebook(self, -1, style=wx.NB_BOTTOM)
self.sheet1 = MySheet(nb)
self.sheet2 = MySheet(nb)
self.sheet3 = MySheet(nb)
nb.AddPage(self.sheet1, "Sheet1")
nb.AddPage(self.sheet2, "Sheet2")
nb.AddPage(self.sheet3, "Sheet3")
self.sheet1.SetFocus()
self.StatusBar()
def StatusBar(self):
self.statusbar = self.CreateStatusBar()
def OnQuit(self, event):
self.Close()
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(450, 400))
self.text = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE)
self.Center()
class MyApp(wx.App):
def OnInit(self):
frame = Notebook(None, -1, 'notebook.py')
frame.Show(True)
frame.Center()
frame2 = MyFrame(None, -1, '')
frame2.Show(True)
self.SetTopWindow(frame2)
return True
app = MyApp(0)
app.MainLoop()
Решение
Сделать два виджета на одном кадре очень просто. Вы должны использовать sizer для этого.
В вашем примере вы можете изменить реализацию класса Notebook
на что-то вроде этого:
class Notebook(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 600))
menubar = wx.MenuBar()
file = wx.Menu()
file.Append(101, 'Quit', '' )
menubar.Append(file, "&File")
self.SetMenuBar(menubar)
wx.EVT_MENU(self, 101, self.OnQuit)
nb = wx.Notebook(self, -1, style=wx.NB_BOTTOM)
self.sheet1 = MySheet(nb)
self.sheet2 = MySheet(nb)
self.sheet3 = MySheet(nb)
nb.AddPage(self.sheet1, "Sheet1")
nb.AddPage(self.sheet2, "Sheet2")
nb.AddPage(self.sheet3, "Sheet3")
self.sheet1.SetFocus()
self.StatusBar()
# new code begins here:
# add your text ctrl:
self.text = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE)
# create a new sizer for both controls:
sizer = wx.BoxSizer(wx.VERTICAL)
# add notebook first, with size factor 2:
sizer.Add(nb, 2)
# then text, size factor 1, maximized
sizer.Add(self.text, 1, wx.EXPAND)
# assign the sizer to Frame:
self.SetSizerAndFit(sizer)
Изменен только метод __ init __
. Обратите внимание, что вы можете манипулировать пропорциями между блокнотом и текстовым элементом управления, изменяя второй аргумент метода Add
.
Подробнее о сортировщиках можно узнать из официальной обзорной страницы Sizer .
Другие советы
Да, вы можете использовать сплиттер.
Кроме того, имеет смысл создать панель, поместить в нее свои виджеты (с определителями размера) и добавить эту панель во фрейм.