背景作为python和GUI编程的新手,我想创建一个基于wxpython的GUI应用程序。此GUI将运行一系列测试,在文本文件中编写的测试将运行,其步骤应显示在窗口中。要选择特定测试,请单击该特定测试的复选框(下图中的CheckListCtrl)。测试结果将以MulilineTextCtrl_2Log格式显示
该窗口应如下所示:
我的ASCII艺术不是很好,但不管怎样
|-------------------------------------------------------------|
|WINDOW TITLExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_[]X|
|xxx[SelectAll]xxxxxx[DeselectAll]xxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|[CheckListCtrl] [MultilineTexTCtrl_1]xxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[Refresh]xxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[Execute]xxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxx[MulilineTextCtrl_2Log]xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|_____________________________________________________________|我在创建这个窗口的boxsizers时遇到了麻烦。我在可视化创建面板时遇到了问题
TestList = [('Test1', 'Test1Description1', 'base'), ('Test2', 'Test1Description1', 'base'),'Test3', 'Test1Description3', 'base'),]
class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
def __init__(self, parent):
wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER)
CheckListCtrlMixin.__init__(self)
ListCtrlAutoWidthMixin.__init__(self)
class MainGUI(wx.frame):
panel = wx.Panel(self, -1)
vbox = wx.BoxSizer(wx.VERTICAL)
hbox = wx.BoxSizer(wx.HORIZONTAL)
#topPanel = wx.Panel(panel,-1)
topPanel = wx.Panel(panel, -1,pos=(0,0))
bottomPanel = wx.Panel(panel, -1,pos=(1,0))
self.log = wx.TextCtrl(bottomPanel, -1, style=wx.TE_MULTILINE)
self.list = CheckListCtrl(bottomPanel)
self.list.InsertColumn(0, 'TestID', width=140)
self.list.InsertColumn(1, 'TestDescription')
for i in TestList:
index = self.list.InsertStringItem(sys.maxint, i[0])
self.list.SetStringItem(index, 1, i[1])
self.list.SetStringItem(index, 2, i[2])
vbox2 = wx.BoxSizer(wx.VERTICAL)
sel = wx.Button(topPanel, -1, 'Select All', size=(100, -1))
des = wx.Button(topPanel, -1, 'Deselect All', size=(100, -1))
refresh = wx.Button(bottomPanel, -1, 'Refresh', size=(100, -1))
apply = wx.Button(bottomPanel, -1, 'Execute', size=(100, -1))
self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id=sel.GetId())
self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, id=des.GetId())
self.Bind(wx.EVT_BUTTON, self.OnRefresh, id=refresh.GetId())
self.Bind(wx.EVT_BUTTON, self.OnExecute, id=apply.GetId())
vbox2.Add(sel, 0, wx.TOP, 5)
vbox2.Add(des)
vbox2.Add(apply,wx.RIGHT)
vbox2.Add(refresh)
topPanel.SetSizer(vbox2)
vbox.Add(self.list, 1, wx.EXPAND, 3)
vbox.Add((-1, 10))
vbox.Add(self.log, 0.5, wx.EXPAND)
vbox.Add((-1, 10))
bottomPanel.SetSizer(vbox)
hbox.Add(bottomPanel, 0, wx.EXPAND | wx.RIGHT, 5)
panel.SetSizer(hbox)
self.Centre()
self.Show(True)
def OnSelectAll(self, event):
num = self.list.GetItemCount()
for i in range(num):
self.list.CheckItem(i)
def OnDeselectAll(self, event):
num = self.list.GetItemCount()
for i in range(num):
self.list.CheckItem(i, False)
def OnRefresh(self, event):
num = self.list.GetItemCount()
for i in range(num):
if i == 0: self.log.Clear()
if self.list.IsChecked(i):
self.log.AppendText(self.list.GetItemText(i) + '\n')
def OnExecute(self, event):
num = self.list.GetItemCount()
for i in range(num):
if i == 0: self.log.Clear()
if self.list.IsChecked(i):
self.log.AppendText(self.list.GetItemText(i) + '\n')
app = wx.App()
MainGUI(None, -1, 'Tester')
app.MainLoop()
发布于 2011-10-03 21:57:22
我向您推荐使用wxglade来设计您的GUI。它是快速和有效的,在你有了一些经验之后,你可以做大多数你可以手动做的事情。
wxglade没有您正在使用的wx.lib小部件,如CheckListCtrlMixin或ListCtrlAutoWidthMixin,也没有组合,如您的类CheckListCtrl。
为了能够使用这些功能,请使用可用的小部件临时填充GUI中的一个插槽(p.e.wx.panel),然后在生成代码后,手动将wx.Panel实例化替换为特殊或自定义类的实例化。
最后,您的代码有一些产生异常的主要问题,例如wx.frame (用于wx.Frame)、错误的缩进或未定义的TestList。您的MainGUI类没有__init__方法,也不会初始化父wx.Frame。此外,bottomPanel会添加到hbox大小,但不会添加到topPanel。
您编写的组织不会生成您所描述的GUI结构,而是具有多个小部件的两个面板的结构:

为了更接近您的描述,您至少需要添加两个额外的sizers。使用wxglade,它将为您做所有的事情。
在这里,您已经为类似的设计生成了wxglade代码(用您的CheckListCtrl替换wx.ListCtrl
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# generated by wxGlade HG on Tue Oct 04 12:45:03 2011
import wx
# begin wxGlade: extracode
# end wxGlade
class MainGUI(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: MainGUI.__init__
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.button_3 = wx.Button(self, -1, "Select All")
self.button_4 = wx.Button(self, -1, "DeselectAll")
self.list_ctrl_1 = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
self.text_ctrl_1 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE)
self.button_1 = wx.Button(self, -1, "Refresh")
self.button_2 = wx.Button(self, -1, "Execute")
self.text_ctrl_2 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE)
self.__set_properties()
self.__do_layout()
# end wxGlade
def __set_properties(self):
# begin wxGlade: MainGUI.__set_properties
self.SetTitle("frame_1")
self.SetBackgroundColour(wx.Colour(255, 170, 5))
self.list_ctrl_1.SetMinSize((200, 264))
# end wxGlade
def __do_layout(self):
# begin wxGlade: MainGUI.__do_layout
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
sizer_3 = wx.BoxSizer(wx.VERTICAL)
sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
sizer_4.Add(self.button_3, 0, wx.ALL, 5)
sizer_4.Add(self.button_4, 0, wx.ALL, 5)
sizer_4.Add((20, 20), 1, wx.EXPAND, 0)
sizer_1.Add(sizer_4, 0, wx.EXPAND, 0)
sizer_2.Add(self.list_ctrl_1, 0, wx.ALL|wx.EXPAND, 5)
sizer_2.Add(self.text_ctrl_1, 0, wx.ALL|wx.EXPAND, 5)
sizer_3.Add(self.button_1, 0, wx.ALL, 5)
sizer_3.Add(self.button_2, 0, wx.ALL, 5)
sizer_2.Add(sizer_3, 0, wx.EXPAND, 0)
sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
sizer_1.Add(self.text_ctrl_2, 0, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer_1)
sizer_1.Fit(self)
self.Layout()
# end wxGlade
# end of class MainGUI
if __name__ == "__main__":
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
frame_1 = MainGUI(None, -1, "")
app.SetTopWindow(frame_1)
frame_1.Show()
app.MainLoop()以及你的表情:

注意,正如在其他答案中所说,不需要将您的小部件放在面板(widget(panel,..))中,也不需要将面板放在sizers中。它可以工作,但更好的方法是将您的小部件(作为frame -> widget(self,..)的子控件)放入sizers (sizerx.Add(widget,..))中,并将sizers放入sizers (sizery.Add(sizerx))中以构建结构。
通常,您不会修改此代码。相反,您可以子类化它来添加您的功能或您需要的任何花哨的附加内容。这样,您就可以再次使用wxglade来更改widgets的位置,从而添加额外的widget或sizer,并重新生成完整的文件。
发布于 2011-10-03 22:04:00
你并不真的需要那么多额外的面板。事实上,除了wx.Notebooks之类的代码,您很少需要一个以上的代码。相反,我发现将这类事情可视化的最简单的方法是在一张纸上画出来,然后在东西周围画矩形。为此,我将拥有一个垂直方向的主BoxSizer。然后,我将使用两个水平的BoxSizers作为按钮和旁边的控件。如果您必须以这种方式定位其他三个单个小部件,那么您可能需要一些带有间隔符的其他BoxSizers。无论如何,一旦您在各种BoxSizers中拥有了小部件,您就可以将它们添加到MainSizer中,就完成了。
或者,您可以使用带有几个间隔符的GridSizer用于最后三个字符。
https://stackoverflow.com/questions/7633997
复制相似问题