gpt4 book ai didi

wxpython - 安排一个 wxpython 窗口从它的内容中明智地继承它的大小

转载 作者:行者123 更新时间:2023-12-01 11:50:29 33 4
gpt4 key购买 nike

我已经编写了我的第一个 wxpython 应用程序并且它运行良好,但是我在正确调整主窗口的大小方面遇到了困难。该面板包含一个 wx.BoxSizer,后者又包含一个 wx.FlexGridSizer,而后者又包含 6 个 wx.TextCtrl

我读过的教程似乎侧重于手动设置尺寸。我真正想做的是让 TextCtrl 计算出包含给定字体(比如“WWW”)的 3 个字符的大小,然后自动确定FlexGridSizer 和主窗口的大小。我不需要担心调整布局的大小(所以可能不需要 Sizer?),我只希望自动确定大小,而不是我将魔术常量放入程序中。

import wx
from names_as_vs import name_sum, name_mult

NAME_SIZE = 35

class MyForm(wx.Frame):
def __init__(self, parent,title):
wx.Frame.__init__(self,parent,title=title,size=(405,200))

self.default_init_UI()
self.init_UI()
self.Show()

def default_init_UI(self):
"""Do all the standard UI stuff"""
file_menu = wx.Menu()
menuAbout = file_menu.Append(wx.ID_ABOUT,"About\tCtrl-A")
menuExit = file_menu.Append(wx.ID_EXIT,"Quit\tCtrl-Q")

menu_bar = wx.MenuBar()
menu_bar.Append(file_menu,"File")
self.SetMenuBar(menu_bar)

self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

def init_UI(self):
"""Particular UI setup for this program"""

hbox = wx.BoxSizer(wx.HORIZONTAL)
panel = wx.Panel(self)
fgs = wx.FlexGridSizer(2,5,9,9)

fixed_elts_args = {"size":(30,70)}
plus = wx.StaticText(panel, label="+", **fixed_elts_args)
times = wx.StaticText(panel, label=".",**fixed_elts_args)

equals1 = wx.Button(panel, label="=", **fixed_elts_args)
equals2 = wx.Button(panel, label="=", **fixed_elts_args)
equals1.Bind(wx.EVT_BUTTON, self.compute_sum)
equals2.Bind(wx.EVT_BUTTON, self.compute_mult)

font = wx.Font(48,wx.ROMAN,wx.NORMAL,wx.NORMAL)
text_ctrl_args = {"size":(95,70)}
self.summand1 = wx.TextCtrl(panel, **text_ctrl_args)
self.summand2 = wx.TextCtrl(panel, **text_ctrl_args)
self.scalar = wx.TextCtrl(panel, **text_ctrl_args)
self.multiplicand = wx.TextCtrl(panel, **text_ctrl_args)
self.sum_result = wx.TextCtrl(panel, style = wx.TE_READONLY, **text_ctrl_args)
self.mult_result = wx.TextCtrl(panel, style = wx.TE_READONLY, **text_ctrl_args)

for ctrl in (plus,times,equals1,equals2,self.summand1,self.summand2,
self.scalar,self.multiplicand,self.sum_result,self.mult_result):
ctrl.SetFont(font)

fgs.AddMany([
self.summand1,plus,self.summand2,equals1,self.sum_result,
self.scalar,times,self.multiplicand,equals2,self.mult_result
])

hbox.Add(fgs, proportion=1, flag= wx.ALL, border=15)
panel.SetSizer(hbox)

def OnAbout(self,e):
dlg = wx.MessageDialog(self, "A GUI implementation of 815 as a vector space", "About 815 as a vector space", wx.OK)
dlg.ShowModal() # Shows it
dlg.Destroy() # finally destroy it when finished.

def OnExit(self,e):
self.Close(True) # Close the frame.

def compute_sum(self,e):
"""Computes the sum of the names in summand1 and summand2 and displays the result in self.sum_result"""
n1 = self.summand1.GetValue()
n2 = self.summand2.GetValue()
self.sum_result.SetValue(name_sum(n1,n2))

def compute_mult(self,e):
"""
Computes the scalar multiple of the name in multiplicand by the scalar in scalar and displays the result in self.mult_result
"""
n = self.multiplicand.GetValue()
lamb = self.scalar.GetValue()
self.mult_result.SetValue(name_mult(lamb,n))

最佳答案

您需要执行两个步骤来解决您的问题。

第一步是计算您的字符串(以“WWW”为例)的宽度。请看this SO question about computing string widhs in pixels using wxpython .一旦你有了宽度和高度,你就可以设置你的 wx.TextCtrl 大小。

第二步是设置wx.Frame 大小。我想开始说,在 wxpython 术语中,任何可以出现在屏幕上的对象都称为窗口,而大多数用户会称之为窗口(即 MS Windows 中带有最小化/最大化/关闭按钮的东西)称为框架。我知道这会让人感到困惑。

所以您想使用内容的大小自动设置框架的大小。简单的!您想要使用 Fit() 方法 ( documentation )。您也可以使用 SetSizerAndFit() 方法 ( documentation ),但这只是一个同时调用 SetSizer()Fit() 同时。 Fit() 方法查看对象内容的大小并相应地调整该对象的大小。不幸的是,在您的特定代码中并没有那么简单。

在您的代码中,您有一个 MyForm(一个 wx.Frame 实例),其中包含一个 wx.Panel,然后包含您的 sizer 和你的 wx.TextCtrl。不幸的是,这会导致根据内容计算 MyForm 的大小时出现问题,因此调用 Fit() 只会将其设置为默认大小。原因是 wx.Frame 根据它们的 sizer(由 SetSizer() 指定)计算它们的大小,而当前的 MyForm 没有一个 sizer,因此它无法根据 wx.Panel 的内容计算大小。幸运的是,这个问题有两种解决方案,而且都很简单。

<强>1。删除 panel 并直接将所有内容设置为 MyForm 的子项,然后调用 SetSizerAndFit()

这看起来像这样:

def init_UI(self):

[...]

#note that the parent is now "self" and not "panel"
self.multiplicand = wx.TextCtrl(self, **text_ctrl_args)
self.sum_result = wx.TextCtrl(self, style = wx.TE_READONLY, **text_ctrl_args)
self.mult_result = wx.TextCtrl(self, style = wx.TE_READONLY, **text_ctrl_args)

[...]

self.SetSizerAndFit(hbox)


<强>2。将 panel 放在另一个 sizer 中,并在 MyForm

上调用 SetSizerAndFit()

看起来像这样:

def init_UI(self):

[...]

panel.SetSizer(hbox)

sizer = wx.BoxSizer(wx.Horizontal)
sizer.Add(panel)
self.SetSizerAndFit(sizer)


最后,我想快速解释一下为什么教程倾向于使用那些“魔数(Magic Number)”。 UI 设计很困难,有时您需要像素完美的东西。如果您开发的应用程序要在具有不同设置和屏幕分辨率甚至不同操作系统的不同计算机上使用,要确保所有内容的显示一致需要明确设置字体和大小等内容,而不是依赖于系统默认值。随着您的进步并开始制作更复杂的 wxpython 应用程序,您会遇到问题,有时对象的大小计算不正确并且使用我告诉您使用的方法仍然会使您的窗口太大/太小。请记住这一点,继续前进。

关于wxpython - 安排一个 wxpython 窗口从它的内容中明智地继承它的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11693669/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com