正如我在上一个问题中所提到的,我试图在功能上做一些类似向导的东西.我已经选择了添加了sizer的单帧.我为每个希望用户看到的屏幕构建面板,将它们添加到框架的sizer中,然后.Hide()通过一个面板在面板之间切换,然后.ShowYourself()在下一个面板上调用自定义面板.显然,我希望按钮与用户在整个过程中保持同一位置.
我通过"后退"和"下一步"按钮将两个面板链接在一个无限循环中,这样你就可以看到发生了什么.第一个小组看起来很棒; tom10的代码在那个级别上工作,因为它避开了我最初的,过度花哨的尝试,边界各处飞行.然后第二个小组似乎缩小到最低限度.当我们返回第一个面板时,这里也发生了收缩.为什么它在第一个面板上看起来很好,但是在我返回后没有?.Fit()如果我不想要10像素乘10像素的灰色,为什么需要调用?如果有必要,为什么会.Fit()给出不一致的结果?
这个无限循环似乎是我对此经历的一个特征:我在面板上修复了布局,但却发现切换会破坏其他面板的布局.我解决了这个问题,通过使用sizer_h.Add(self.panel1, 0)而不是sizer_h.Add(self.panel1, 1, wx.EXPAND),现在我的布局再次关闭.
到目前为止,我的"解决方案"是为mastersizer.SetMinSize((475, 592))每个面板的主sizer 添加一个(在下面的代码中注释掉).这是一个肮脏的解决方案,因为1)我必须找到通过试验和错误工作的数字(宽度为-5像素,高度为-28像素).2)我不明白为什么潜在的问题仍然存在.
什么是正确的,非丑陋的解决方案?如果切换面板不是将所有面板同时添加到框架的大小调整器中,而是应该.Detach()从框架的大小调整器中将面板包含在内,然后.Add()将下一个面板连接到框架的大小调整器上?是否有一种.JustMakeThisFillThePanel()隐藏在wxWidgets和wxPython文档在线的错过的方法?
我显然在布局的心理模型中遗漏了一些东西.粘贴在下面的极简主义代码.

import wx
import sys
class My_App(wx.App):
def OnInit(self):
self.frame = My_Frame(None)
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def OnExit(self):
print 'Dying ...'
class My_Frame(wx.Frame):
def __init__(self, image, parent=None,id=-1, title='Generic Title', pos=wx.DefaultPosition, style=wx.CAPTION | wx.STAY_ON_TOP):
size = (480, 620)
wx.Frame.__init__(self, parent, id, 'Program Title', pos, size, …Run Code Online (Sandbox Code Playgroud) 我正在使用栅格化器将两块面板放在一个框架内.
control_panel = wx.Panel(self, id=ID_CONTROL_PANEL)
main_panel = wx.Panel(self, id=ID_MAIN_PANEL)
frame_sizer = wx.GridBagSizer(1, 1)
frame_sizer.Add(control_panel, (0, 0), (2, 5), flag=wx.EXPAND)
frame_sizer.Add(main_panel, (2, 0), (5, 5), flag=wx.EXPAND)
frame_sizer.AddGrowableRow(0)
frame_sizer.AddGrowableCol(0)
self.SetSizer(frame_sizer)
Run Code Online (Sandbox Code Playgroud)
我希望control_panel位于main_panel之上(如上所示).然而,这是我得到的输出:

当我指出相反的情况时,我不知道为什么顶部面板比底部面板大得多.(2,5)为顶部,(5,5)为底部.它也有一个奇怪的行为,当我调整它更小,它基本上给了我想要的东西(见下图),但我不知道如何保持比率,当我再次变大.

然而,当您开始调整大小(即使是少量)时,您可以看到(下方)形状和比率在另一个方向上发生显着变化(底部变得更小,顶部变得更大).

仍然试图学习这个sizer,并且无法用我见过的任何例子找到这个问题.还尝试了所有参数并做了一些测试,我无法弄清楚这里发生了什么.任何帮助将非常感激.
编辑:下面的图片添加,以帮助评论如下.

我正在使用wx.Python并且有一组对象我想要"包裹"在类似于此的静态框中:

然而,该教程使用位置大小,而我正在使用sizer.我很难把物品放进去:

而是他们在静态框下面.如何使用Sizer在静态框中包含对象而不是位置?
这是我的代码:
# Date and Graph Type Selection
self.dateLbl = wx.StaticBox(self, -1, 'Date Range:', size=(240, 140))
self.dategraphSizer = wx.BoxSizer(wx.VERTICAL)
self.dategraphSizer.Add(self.dateLbl, 0, wx.ALL|wx.LEFT, 5)
# Date Range Selection
self.dateSizer = wx.BoxSizer(wx.HORIZONTAL)
self.dateone = wx.TextCtrl(self, -1, style=wx.ALIGN_LEFT)
self.datetwo = wx.TextCtrl(self, -1, style=wx.ALIGN_LEFT)
self.date2Lbl = wx.StaticText(self, -1, "TO")
self.dateSizer.Add(self.dateone, 0, wx.ALL|wx.CENTER, 2)
self.dateSizer.Add(self.date2Lbl, 0, wx.ALL|wx.CENTER, 2)
self.dateSizer.Add(self.datetwo, 0, wx.ALL|wx.CENTER, 2)
# Date Quick Selection Buttons
self.dategraphSizer.Add(self.dateSizer, 0, wx.ALL|wx.CENTER, 5)
self.todayButton = wx.Button(self, -1, 'Today Only')
self.dategraphSizer.Add(self.todayButton, 0, wx.ALL|wx.LEFT, 5) …Run Code Online (Sandbox Code Playgroud) wx.SpinCtrl仅限于整数旋转,而不是浮动.因此,我正在构建一个wx.TextCtrl+ wx.SpinButtoncombo类,这使我能够跨越浮点数.我能够以编程方式对它们进行大小和布局,以使组合看起来与普通组件完全相同wx.SpinCtrl.
我从这里继承了这个组合,wx.TextCtrl因为我希望它的父面板能够捕获wx.EVT_TEXT事件.如果你能改进我的这个论点,我将不胜感激.
在wx.EVT_SPIN_UP与wx.EVT_SPIN_DOWN从事件wx.SpinButton都是内实现和父框架并不关心这些事件.
现在,我刚碰到一堵砖墙.我的组合类与sizer不兼容.在.Add()将组合类放到a之后wx.GridBagSizer,只有在wx.TextCtrl它内部布局wx.GridBagSizer.该wx.SpinButton由自己留在了自己.但是wx.EVT_SPIN*绑定工作得很好.
我的问题是布局.如果我想wx.GridBagSizer将它视为一个小部件,我该如何编写该类?
这是我的组合类代码:
class SpinnerSuper(wx.TextCtrl):
def __init__(self, parent, max):
wx.TextCtrl.__init__(self, parent=parent, size=(48, -1))
spin = wx.SpinButton(parent=parent, style=wx.SP_VERTICAL, size=(-1, 21))
self.OnInit()
self.layout(spin)
self.internalBindings(spin)
self.SizerFlag = wx.ALIGN_CENTER
self.min = 0
self.max = max
def OnInit(self):
self.SetValue(u"0.000")
def layout(self, spin):
pos = self.GetPosition()
size = self.GetSize()
RightEdge = pos[0] …Run Code Online (Sandbox Code Playgroud) 我有一个wxWindow.在那里我有一个wxBoxSize(垂直).sizer有3个子控件.
我希望能够隐藏三个子控件之一,并让sizer及其父控件自动调整大小.例如,当我隐藏sizer的一个子控件时,窗口减少200像素.
现在,我显示隐藏某些控件,并调整窗口大小的方法如下所示:(硬编码,不完整)
void GenUIAanleverOptionsDialog::OnToggleButtonShowLabels( wxCommandEvent& event )
{
if(this->btnShowLabels->GetValue())
{
this->pnlInfoLabels->Show(true);
this->SetSize(this->GetSize().GetWidth(), 573);
}
else
{
this->pnlInfoLabels->Show(false);
this->SetSize(this->GetSize().GetWidth(), 294);
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个包含单个项目的WxPython框架,例如:
class Panel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.text = wx.StaticText(self, label='Panel 1')
Run Code Online (Sandbox Code Playgroud)
我有一个框架包含几个面板,包括这个面板,尺寸由sizer统治.我想StaticText扩大这一点.使用BoxSizer仅包含文本和设置wx.EXPAND标志就可以了,但是对于一个项目使用sizer似乎很愚蠢.
更简单的解决方案?
(我可以直接将其添加StaticText到父框架的sizer中,但对于我的设计,直接从框架开始更有意义.)
我刚刚意识到,创建BoxSizer一个项目时不能使用wx.VERTICAL:
class Panel1(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.BackgroundColour = 'red'
sizer = wx.BoxSizer(wx.VERTICAL)
self.Sizer = sizer
self.list = wx.ListBox(self, choices=[str(i) for i in xrange(100)])
sizer.Add(self.list, 0, wx.EXPAND)
sizer.Fit(self)
Run Code Online (Sandbox Code Playgroud)
当然可以使用一个项目,但如果我想稍后垂直添加项目并仍然使它们都展开(例如,当用户的窗口展开时)怎么办?
编辑:嗯,我刚发现必须使用这个比例才能让boxsizers以两种方式成长.(即,在1 BoxSizer.Add的呼叫中将0替换为0.)
在我看来,以下代码应该在窗口的中心显示文本; 也就是说,在内板的中心.然而,它并没有,我想知道为什么不.如果运行代码,您将在框架中间看到一个白色面板,150px乘150px.我根本不希望这个区域的大小发生变化,但是当我开始添加一些文本(txt在代码片段中间取消注释变量)时,面板总是收缩以适应文本.即使指定StaticText与面板匹配的大小也不是解决方案,因为文本不会居中对齐.
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
self.rootPanel = wx.Panel(self)
innerPanel = wx.Panel(self.rootPanel,-1, size=(150,150), style=wx.ALIGN_CENTER)
innerPanel.SetBackgroundColour('WHITE')
hbox = wx.BoxSizer(wx.HORIZONTAL)
vbox = wx.BoxSizer(wx.VERTICAL)
# I want this line visible in the CENTRE of the inner panel
#txt = wx.StaticText(innerPanel, id=-1, label="TEXT HERE",style=wx.ALIGN_CENTER, name="")
hbox.Add(innerPanel, 0, wx.ALL|wx.ALIGN_CENTER)
vbox.Add(hbox, 1, wx.ALL|wx.ALIGN_CENTER, 5)
self.rootPanel.SetSizer(vbox)
vbox.Fit(self)
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'wxBoxSizer.py')
frame.Show(True)
frame.Center()
return True
app = MyApp(0)
app.MainLoop()
Run Code Online (Sandbox Code Playgroud) 我想在 sizer 中隐藏一个小部件,而不是留下空白空间。我不想删除小部件,因为我想稍后再显示它。
有没有办法隐藏小部件并在它移动到一个空间以填充空位后显示显示的小部件?
这是一个留有空格的简单示例:
import wx
class MyPanel(wx.Panel):
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
sizer = wx.GridSizer(1, 3, 0, 0)
a = wx.Button(self, -1, 'a')
b = wx.Button(self, -1, 'b')
c = wx.Button(self, -1, 'c')
sizer.Add(a, 0, 0, 0)
sizer.Add(b, 0, 0, 0)
sizer.Add(c, 0, 0, 0)
b.Hide()
self.SetSizer(sizer)
class MyFrame(wx.Frame):
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, parent=None, title="Remove Spaces")
panel = MyPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(panel, 1, wx.EXPAND)
self.SetSizer(sizer)
self.Fit()
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = …Run Code Online (Sandbox Code Playgroud) 我正在尝试研究wxPython和sizer,并将以下示例放在一起:
import wx
class MyTestFrame(wx.Frame):
def __init__(self, parent, title):
super(MyTestFrame, self).__init__(parent, title=title,
size=(250, 150))
# the master panel of the frame - "Add a panel so it looks correct on all platforms"
self.panel = wx.Panel(self, wx.ID_ANY)
# self.panel.SetBackgroundColour(wx.Colour(124, 224, 124)) # to confirm the square is the panel
# want these buttons absolutely positioned
btn_A = wx.Button(self, id=1, label='A', pos=(10, 10), size=(30, 30))
btn_A.SetBackgroundColour(wx.Colour(224, 124, 124))
btn_B = wx.Button(self, id=2, label='B', pos=(45, 10), size=(30, 30))
btn_C = wx.Button(self, id=3, label='C', …Run Code Online (Sandbox Code Playgroud) 在wxPython中我有GridBagSizer,GS,与一些嵌套大小测定器s1和s2和一个按钮b,在单个小区中.
在一个EVT_BUTTON事件上,我得到了按钮对象.要将网格中的按钮对象移动到不同的网格单元格,我需要移动顶级sizer,s1,这是GridBagSizer的直接"子"(如果这是正确的术语),gs.找到顶级sizer的最佳方法是什么?
object.GetContainingSizer()返回按钮对象的sizer,s2,但我看不到如何到达s1.我是否需要在s2(或b)对象中存储对s1的引用?这看起来相当不优雅?
# pseudocode
panel=wx.Panel( None )
gs= wx.GridBagSizer()
s1= wx.BoxSizer()
s2= wx.BoxSizer()
b= wx.Button(panel, wx.ID_ANY, 'AButton')
s2.Add( b )
s1.Add( s2 )
gs.Add( s1, (row,col))
Run Code Online (Sandbox Code Playgroud)
答案(到目前为止):我发现了一段我不知道应该归功于哪些代码 - 似乎与dabo有关.它在dGridSizer.py中,但它做了类似我正在寻找的东西:
szitm= grid_sizer.FindItemAtPosition( (row,col) )
if szitm:
if szitm.IsWindow():
itm=szitm.GetWindow()
elif szitm.IsSizer():
itm=szitm.GetSizer()
try: # in case some other IsSomething() I don't have covered
grid_sizer.SetItemPosition( itm, (newrow,col))
except:
pass
Run Code Online (Sandbox Code Playgroud)
到目前为止,这似乎适用于我在网格中的所有情况.目前还不确定我是否理解它,我将不得不深入研究代码 - 现在只需要完成这项工作.