【问题标题】:wxPython simple GUI proving elusivewxPython 简单的 GUI 证明难以捉摸
【发布时间】:2020-06-02 19:47:48
【问题描述】:

我已经在 GNU/Linux 上研究 Python 3.8 和 wxPython 4 (Phoenix) 好几天了,但进展甚微。我需要一个非常简单的 GUI,一个滚动的画布占据了全屏窗口的大部分,一个滚动的面板在其下方保存了大约 4 行文本。我想要画布和面板周围的一些边距。我希望能够自动(而不是绝对)定位。我遇到的问题是 1) 滚动条没有出现,2) 我使用的是绝对定位,我不确定我放置的尺寸器是否正常工作。

我一直在四处寻找,尝试各种变化。我已经阅读了我使用的所有调用的 API 文档。我看过演示和示例。我看过我能在 O'Reilly 上找到的每一本书。我仍然觉得我对理解 wxPython 的架构还有些摸不着头脑。我在 Python 中使用 TkInter 和 Qt 以及其他语言开发了许多其他 GUI 应用程序。所以,我感觉这里很密集。

这是当前应用的外观:

这是我当前的代码:

#!/usr/bin/env python3.8

import wx

class MainWindow(wx.Frame):

  def __init__(self, title):

    screen_x = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
    screen_y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
    size_value = wx.Size(screen_x, screen_y)

    wx.Frame.__init__(self, None, title=title, size=size_value)
    # why does this not work?
    # super(MainWindow, self).__init__(self, None, title=title,
    #                                  size=size_value)

    canvas1 = wx.ScrolledCanvas(self, size=wx.Size(screen_x-30, 300),
                                pos=wx.Point(15, 15))
    canvas1.SetBackgroundColour('#cc20cc')
    canvas1.AlwaysShowScrollbars(True, True)
    canvas1.SetAutoLayout(1)
    canvas1.SetScrollbar(wx.VERTICAL, 0, 10, 100)
    canvas1.SetScrollbar(wx.HORIZONTAL, 0, 10, 100)
    canvas1.SetScrollRate(1, 1)

    # with open('/home/kbuchs/.emacs') as fp:
    #     txt_value = fp.read()
    # txt = wx.StaticText(canvas1, label=txt_value)

    canvas2 = wx.ScrolledCanvas(self, size=wx.Size(screen_x-30, 1000),
                                pos=wx.Point(15, 315))
    canvas2.SetBackgroundColour('#d0d020')
    canvas2.AlwaysShowScrollbars(True, True)
    canvas2.SetAutoLayout(1)
    canvas2.SetScrollRate(1, 1)

    with open('/home/kbuchs/.bashrc') as fp:
        txt_value2 = fp.read()
    txt2 = wx.StaticText(canvas2, label=txt_value2)

    sizer = wx.BoxSizer(wx.VERTICAL)
    self.sizer = sizer

    sizer.Add(canvas1, wx.ID_ANY, wx.ALL, 20)
    sizer.Add(canvas2, wx.ID_ANY, wx.ALL, 40)

    self.Show()


app = wx.App()
MainWindow('Git Branch History')
app.MainLoop()

更新 6 月 3 日晚上 10:30 CDT。 这是我在 Saxony 的 Rolf 示例之后对代码的最新修订尝试。似乎两个 txt 部分(如果未注释)没有被写入画布/面板,但两者都在框架的顶部重叠。此外,仍然没有滚动。

#!/usr/bin/env python3.8

import wx
import wx.lib.scrolledpanel as sp

class MainWindow(wx.Frame):

  def __init__(self, title):

    screen_x = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
    screen_y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
    size_value = wx.Size(screen_x, screen_y)

    super(MainWindow, self).__init__(None, title=title, size=size_value)

    # canvas1 = wx.ScrolledCanvas(self, id=-1,
    canvas1 = sp.ScrolledPanel(self, id=-1,
                               size=wx.Size(screen_x, screen_y-200))
                                # pos=wx.Point(15, 15))
    canvas1.SetBackgroundColour('#ccffff')
    canvas1.AlwaysShowScrollbars(True, True)
    canvas1.SetAutoLayout(1)
    canvas1.SetupScrolling()

    with open('/home/kbuchs/.emacs') as fp:
        txt_value1 = fp.read()
    long_line = 900*'-' + '\n'
    # txt1 = wx.StaticText(canvas1, label=long_line+txt_value1)
    # txt1.SetBackgroundColour('#eeffff')

    # txt1Sizer = wx.BoxSizer(wx.VERTICAL)
    # txt1Sizer.Add(txt1, proportion=0, border=5)

    canvas1Sizer = wx.BoxSizer(wx.VERTICAL)
    canvas1Sizer.Add(canvas1, proportion=0, flag=wx.CENTER|wx.ALL|wx.EXPAND, border=5)
    # canvas1Sizer.Add(txt1Sizer, proportion=0)
    # canvas1Sizer.Add(txt1, proportion=0, flag=wx.ALL, border=5)

    # canvas2 = wx.ScrolledCanvas(self, id=-1,
    canvas2 = sp.ScrolledPanel(self, id=-1,
                               size=wx.Size(screen_x, 200))
                                # pos=wx.Point(15, 315))

    canvas2.SetBackgroundColour('#ffffcc')
    canvas2.AlwaysShowScrollbars(True, True)
    canvas2.SetAutoLayout(1)
    canvas2.SetupScrolling()

    with open('/home/kbuchs/.bashrc') as fp:
        txt_value2 = fp.read()
    # txt2 = wx.StaticText(canvas2, label=long_line+txt_value2)
    # txt2.SetBackgroundColour('#ffffee')

    canvas2Sizer = wx.BoxSizer(wx.VERTICAL)
    canvas2Sizer.Add(canvas2, proportion=0, flag=wx.CENTER|wx.ALL|wx.EXPAND, border=5)
    # canvas2Sizer.Add(txt2, proportion=0, flag=wx.CENTER|wx.ALL, border=20)

    sizer = wx.BoxSizer(wx.VERTICAL)
    self.sizer = sizer

    sizer.Add(canvas1Sizer, proportion=0, flag=wx.CENTER|wx.ALL|wx.EXPAND, border=5)
    sizer.Add(canvas2Sizer, proportion=0, flag=wx.CENTER|wx.ALL|wx.EXPAND, border=5)

    self.Show()


app = wx.App()
MainWindow('Git Branch History')
app.MainLoop()

【问题讨论】:

  • 我现在没有时间,但您需要在演出前分配尺寸器,即self.SetSizer(sizer)。使用尺寸测量仪直接定位可能会产生奇怪的外观。 Sizer 一开始会让你发疯;)
  • 嗯?尺寸更大的东西都是在演出之前。
  • 是的,但你忽略了SetSizer,这是我的意思!

标签: wxpython


【解决方案1】:

我会再试一次,因为您修改了问题但没有发表评论,所以我不知道。
您似乎对SetSizer 有一个盲点,在 cmets 中提到了两次,并在我的第一个答案中使用。
这就像收拾行李箱,然后背着背包去度假。

这是您的第二个代码示例,已修改。

import wx
import wx.lib.scrolledpanel as sp

class MainWindow(wx.Frame):

  def __init__(self, title):

    screen_x = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
    screen_y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
    size_value = wx.Size(screen_x, screen_y)

    super(MainWindow, self).__init__(None, title=title, size=size_value)

    canvas1 = sp.ScrolledPanel(self, id=-1,)

    canvas1.SetBackgroundColour('#ccffff')
    canvas1.SetupScrolling(scroll_x=True, scroll_y=True, rate_x=20, rate_y=20, scrollToTop=True, scrollIntoView=True)
    canvas1.AlwaysShowScrollbars(True, True)

    with open('tips.txt') as fp:
        txt_value1 = fp.read()
    long_line = 600*'y' + 'X\n'
    txt1 = wx.StaticText(canvas1, label=long_line+txt_value1)
    txt1.SetBackgroundColour('#eeffff')

    canvas1Sizer = wx.BoxSizer(wx.VERTICAL)
    canvas1Sizer.Add(txt1, proportion=0, flag=wx.ALL|wx.EXPAND, border=5)

    canvas2 = sp.ScrolledPanel(self, id=-1)

    canvas2.SetBackgroundColour('#ffffcc')
    canvas2.SetupScrolling(scroll_x=True, scroll_y=True, rate_x=20, rate_y=20, scrollToTop=True, scrollIntoView=True)
    canvas2.AlwaysShowScrollbars(True, True)

    with open('tips.txt') as fp:
        txt_value2 = fp.read()
    txt2 = wx.StaticText(canvas2, label=long_line+txt_value2)
    txt2.SetBackgroundColour('#ffffee')

    canvas2Sizer = wx.BoxSizer(wx.VERTICAL)
    canvas2Sizer.Add(txt2, proportion=0, flag=wx.ALL|wx.EXPAND, border=20)

    canvas1.SetSizer(canvas1Sizer)
    canvas2.SetSizer(canvas2Sizer)

    sizer = wx.BoxSizer(wx.VERTICAL)

    sizer.Add(canvas1, proportion=1, flag=wx.ALL|wx.EXPAND, border=5)
    sizer.Add(canvas2, proportion=1, flag=wx.ALL|wx.EXPAND, border=5)

    self.SetSizer(sizer)

    self.Show()

app = wx.App()
MainWindow('Git Branch History')
app.MainLoop()

【讨论】:

  • 谢谢,罗尔夫。我以为您指的是为 MainWindow wx.Frame 设置 sizer。为此,我有 self.sizer = sizer,我理解这正是 self.SetSizer 所做的。我发现我对每个画布所需的单独尺寸器感到困惑,因为我实际上将这些尺寸器添加到 wx.Frame 中。但是我看到我应该将画布添加到框架中并为每个画布设置大小。我想我有一个心理形象问题,认为 sizer 包含它大小的东西(如 Tk)。
  • 有趣的是,每个画布尺寸器中只有一个东西,即静态文本。在这种情况下,这些尺寸器甚至是必要的吗?
  • 回答我自己的问题 - 是的,这些尺寸是必要的。
【解决方案2】:

我将扔掉你的画布并用 TextCtrl 替换它,你可以使用任何适合你要求的东西。
希望这将为您指明正确的方向,其中有足够的内容可以指明方向。

import wx

class MainWindow(wx.Frame):
    def __init__(self, parent, title):

        screen_x = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
        screen_y = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
        size_value = wx.Size(screen_x, screen_y)

        super(MainWindow, self).__init__(parent, title=title, size=size_value)

        #Define widgets
        tc1 = wx.TextCtrl(self, size=wx.Size(screen_x-30, 200),
            style= wx.TE_MULTILINE|wx.TE_PROCESS_ENTER|wx.TE_DONTWRAP|wx.TE_AUTO_URL)
        tc1.SetBackgroundColour('#cc2000')

        # Some Control buttons
        self.b1 = wx.Button(self, -1, "Button 1")
        self.b2 = wx.Button(self, -1, "Button 2")
        self.b3 = wx.Button(self, -1, "Quit")

        tc2 = wx.TextCtrl(self, size=wx.Size(screen_x-30, 1000),
            style= wx.TE_MULTILINE|wx.TE_PROCESS_ENTER|wx.TE_DONTWRAP)
        tc2.SetBackgroundColour('#d0d020')

        #Bind events to functions
        self.b3.Bind(wx.EVT_BUTTON, self.OnQuit)

        #Load initial data
        try:
            with open('tips.txt') as fp:
                txt_value2 = fp.read()
        except:
            txt_value2 = "tips.txt file not found"

        txt_value2 = txt_value2 * 20

        tc1.AppendText("No data yet\n")
        tc1.AppendText("www.nodatayet.com\n")
        tc1.AppendText("                                 "*20)
        tc1.AppendText("X\n")

        tc2.write(txt_value2)

        #Define sizers
        sizer = wx.BoxSizer(wx.VERTICAL)
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)

        #Populate sizers
        button_sizer.Add(self.b1)
        button_sizer.Add(self.b2)
        button_sizer.Add(self.b3)

        sizer.Add(tc1, proportion=0, flag=wx.ALL, border=20)
        sizer.Add(button_sizer, proportion=0, flag=wx.LEFT, border=40)
        sizer.Add(tc2, proportion=1, flag=wx.ALL, border=40)

        self.SetSizer(sizer)
        self.Show()

    def OnQuit(self, event):
        self.Destroy()

app = wx.App()
MainWindow(None,'Git Branch History')
app.MainLoop()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多