我是wxPython的新手,正在学习如何使用sizer。我已经成功地创建了一个似乎正确对齐的面板,但是我想在它的下面直接放置一个新的面板,并且遇到了问题。我想让第一个绿色背景的面板有一个固定的高度,但是绿色背景填满了整个框架,尽管这个面板的内容似乎已经按照我的要求对齐了。 谢谢你的帮助。
这里是一张图片,框架最大限度地填满了我的窗口。
这只是一个单一的面板。面板的内容沿着顶部正确地排列,但是我想让面板停在那些部件的下面,这样我就可以开始一个新的面板。所以绿色不应该填满整个窗口,因为我已经把这个框架的bg设置为绿色。绿色应该停在小部件下面,然后我想添加另一个框架。
这是我的完整代码。
import time
import os
import gc
import wx
import wx.grid
# wxpython app
# read ss from files or live version
class Wx_app(wx.App):
# __init__ gets called first when any class is initialized
def __init__(self):
# intiialize the App window
super().__init__(clearSigInt=True)
# don't set size of the frame, just position. let
# sizers do the sizing?
self.frame = MyFrame(None, pos=(10,10))
# frame class (wx python wind)
class MyFrame(wx.Frame):
def __init__(self, *args, **kwargs):
# ini the frame and show it
super(MyFrame, self).__init__(*args, **kwargs)
# main sizer, will contain all of the other sizers
self.main_sizer = wx.BoxSizer(wx.VERTICAL)
# FONTS
# font to use for the panel in labels, text ctrls, etc
txt_font = wx.Font(18, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
# font to use for buttons is slightly small than txt_font
but_font = wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
# PANEL 1
# first panel is at the top, contains manual pick area plus msg area
self.pick_area_panel = PickAreaPanel(self, txt_font, but_font)
self.main_sizer.Fit(self.pick_area_panel)
# show the frame with panel
self.Show(True)
# panel class
class PickAreaPanel(wx.Panel):
def __init__(self, parent, txt_font, but_font):
# ini
super().__init__(parent=parent)
# set background colour for panel
self.SetBackgroundColour("Green")
# create the sizer for this panel.
# stuff is organized horizontally left to right
self.panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
# NOTE: By setting width to -1, we tell to go with sizer, and height to 100
# sets a fixed height
pick_label = wx.StaticText(self, -1, "Confirm Pick R1 P1: ", size=(240, 25))
pick_label.SetBackgroundColour("Red")
pick_label.SetFont(txt_font)
# input textctrl for the manual pick
pick_input = wx.TextCtrl(self, -1, size=(320, 25))
pick_input.SetFont(txt_font)
# button to confirm manual pick
pick_confirm_but = wx.Button(self, -1, size=(150, 25))
pick_confirm_but.SetLabel("Confirm")
pick_confirm_but.SetFont(but_font)
# PROG MSG AREA
# no fixed size, fills rest of panel after previous elements
# need a nested sizer so can control borders
# and give it a left borcer thats different from its top border
prog_msg_area_sizer = wx.BoxSizer(wx.HORIZONTAL)
prog_msg_area = wx.StaticText(self, -1, "MSG MSG MSG", size=(-1, 25), style=wx.ALIGN_CENTER)
prog_msg_area.SetBackgroundColour("White")
prog_msg_area.SetFont(txt_font)
prog_msg_area_sizer.Add(prog_msg_area, proportion=1, flag=wx.EXPAND|wx.TOP, border=0)
# add elements to panel sizer
self.panel_sizer.Add(pick_label, proportion=0, flag=wx.EXPAND|wx.TOP, border=3)
self.panel_sizer.Add(pick_input, proportion=0, flag=wx.EXPAND)
self.panel_sizer.Add(pick_confirm_but, proportion=0, flag=wx.EXPAND)
# prog msg area has its own horiz sizer so can set a left border diff from top border
self.panel_sizer.Add(prog_msg_area_sizer, proportion=1, flag=wx.EXPAND|wx.LEFT, border=10)
# add panel sizer to the main sizer
# set proporition to 0 so height of panel doesnt change when height of frame changes
# adds a border around the entire panel
parent.main_sizer.Add(self.panel_sizer, proportion=0, flag=wx.EXPAND|wx.ALL, border=15)
# set panel to use the main sizer
# not sure exactly how this works....
self.SetSizer(parent.main_sizer)
wx_app = Wx_app()
if __name__ == '__main__':
wx_app.MainLoop()
修改后的程序与建议的变化。
import time
import os
import gc
import wx
import wx.grid
class Wx_app(wx.App):
def __init__(self):
super().__init__(clearSigInt=True)
self.frame = MyFrame(None, pos=(10,10))
class MyFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super(MyFrame, self).__init__(*args, **kwargs)
self.main_sizer = wx.BoxSizer(wx.VERTICAL)
txt_font = wx.Font(18, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
but_font = wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
self.pick_area_panel = PickAreaPanel(self, txt_font, but_font)
# *******ADDED:
self.SetSizer(self.main_sizer)
self.Show(True)
# panel class
class PickAreaPanel(wx.Panel):
def __init__(self, parent, txt_font, but_font):
super().__init__(parent=parent)
self.SetBackgroundColour("Green")
self.panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
pick_label = wx.StaticText(self, -1, "Confirm Pick R1 P1: ", size=(240, 25))
pick_label.SetBackgroundColour("Red")
pick_label.SetFont(txt_font)
pick_input = wx.TextCtrl(self, -1, size=(320, 25))
pick_input.SetFont(txt_font)
pick_confirm_but = wx.Button(self, -1, size=(150, 25))
pick_confirm_but.SetLabel("Confirm")
pick_confirm_but.SetFont(but_font)
prog_msg_area_sizer = wx.BoxSizer(wx.HORIZONTAL)
prog_msg_area = wx.StaticText(self, -1, "MSG MSG MSG", size=(-1, 25), style=wx.ALIGN_CENTER)
prog_msg_area.SetBackgroundColour("White")
prog_msg_area.SetFont(txt_font)
prog_msg_area_sizer.Add(prog_msg_area, proportion=1, flag=wx.EXPAND|wx.TOP, border=0)
self.panel_sizer.Add(pick_label, proportion=0, flag=wx.EXPAND|wx.TOP, border=3)
self.panel_sizer.Add(pick_input, proportion=0, flag=wx.EXPAND)
self.panel_sizer.Add(pick_confirm_but, proportion=0, flag=wx.EXPAND)
self.panel_sizer.Add(prog_msg_area_sizer, proportion=1, flag=wx.EXPAND|wx.LEFT, border=10)
parent.main_sizer.Add(self.panel_sizer, proportion=0, flag=wx.EXPAND|wx.ALL, border=15)
# CHANGED
self.SetSizer(self.panel_sizer)
wx_app = Wx_app()
if __name__ == '__main__':
wx_app.MainLoop()
我从来没有尝试过将一个类的sizer设置为另一个类的sizer,这就是你在这里所做的。为面板设置sizer,并分别为框架设置sizer.见下图:你会注意到,我已经做了一个面板的副本来说明框架中的2个面板。
import time
import os
import gc
import wx
import wx.grid
# wxpython app
# read ss from files or live version
class Wx_app(wx.App):
# __init__ gets called first when any class is initialized
def __init__(self):
# intiialize the App window
super().__init__(clearSigInt=True)
# don't set size of the frame, just position. let
# sizers do the sizing?
self.frame = MyFrame(None, pos=(10,10))
# frame class (wx python wind)
class MyFrame(wx.Frame):
def __init__(self, *args, **kwargs):
# ini the frame and show it
super(MyFrame, self).__init__(*args, **kwargs)
# main sizer, will contain all of the other sizers
self.main_sizer = wx.BoxSizer(wx.VERTICAL)
# FONTS
# font to use for the panel in labels, text ctrls, etc
txt_font = wx.Font(18, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
# font to use for buttons is slightly small than txt_font
but_font = wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
# PANEL 1
# first panel is at the top, contains manual pick area plus msg area
self.pick_area_panel = PickAreaPanel(self, txt_font, but_font)
self.pick_area_panel2 = PickAreaPanel(self, txt_font, but_font)
self.main_sizer.Add(self.pick_area_panel, proportion=0, flag=wx.EXPAND|wx.ALL, border=10)
self.main_sizer.Add(self.pick_area_panel2, proportion=0, flag=wx.EXPAND|wx.ALL, border=10)
self.SetSizerAndFit(self.main_sizer)
# show the frame with panel
self.Show(True)
# panel class
class PickAreaPanel(wx.Panel):
def __init__(self, parent, txt_font, but_font):
# ini
super().__init__(parent=parent)
# set background colour for panel
self.SetBackgroundColour("Green")
# create the sizer for this panel.
# stuff is organized horizontally left to right
self.panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
# NOTE: By setting width to -1, we tell to go with sizer, and height to 100
# sets a fixed height
pick_label = wx.StaticText(self, -1, "Confirm Pick R1 P1: ", size=(240, 25))
pick_label.SetBackgroundColour("Red")
pick_label.SetFont(txt_font)
# input textctrl for the manual pick
pick_input = wx.TextCtrl(self, -1, size=(320, 25))
pick_input.SetFont(txt_font)
# button to confirm manual pick
pick_confirm_but = wx.Button(self, -1, size=(150, 25))
pick_confirm_but.SetLabel("Confirm")
pick_confirm_but.SetFont(but_font)
# PROG MSG AREA
# no fixed size, fills rest of panel after previous elements
# need a nested sizer so can control borders
# and give it a left borcer thats different from its top border
prog_msg_area_sizer = wx.BoxSizer(wx.HORIZONTAL)
prog_msg_area = wx.StaticText(self, -1, "MSG MSG MSG", size=(-1, 25), style=wx.ALIGN_CENTER)
prog_msg_area.SetBackgroundColour("White")
prog_msg_area.SetFont(txt_font)
prog_msg_area_sizer.Add(prog_msg_area, proportion=1, flag=wx.EXPAND|wx.TOP, border=0)
# add elements to panel sizer
self.panel_sizer.Add(pick_label, proportion=0, flag=wx.EXPAND|wx.TOP, border=3)
self.panel_sizer.Add(pick_input, proportion=0, flag=wx.EXPAND)
self.panel_sizer.Add(pick_confirm_but, proportion=0, flag=wx.EXPAND)
# prog msg area has its own horiz sizer so can set a left border diff from top border
self.panel_sizer.Add(prog_msg_area_sizer)
# add panel sizer to the main sizer
# set proporition to 0 so height of panel doesnt change when height of frame changes
# adds a border around the entire panel
#parent.main_sizer.Add(self.panel_sizer, proportion=0, flag=wx.ALL, border=15)
# set panel to use the main sizer
# not sure exactly how this works....
self.SetSizer(self.panel_sizer)
wx_app = Wx_app()
if __name__ == '__main__':
wx_app.MainLoop()