按钮和wxpython中的刷新显示区域

时间:2018-07-24 16:00:04

标签: python layout wxpython wxpython-phoenix

我是人文学科的老师,他试图改编一个简单的应用程序来帮助老师管理课堂互动-它需要上学,然后允许在课堂上随机召集参加的学生,或者将他们分成小组,或者记录一个旷课的理由,以及以此类推。长期以来,我一直在笔记本电脑上本地运行PHP / MySQL的工作版本,但我希望使其成为可移植的python / sqlite应用程序,并着眼于发布,以供其他教师使用和改进。

但是我对wxPython完全陌生,通常对面向对象的编程并不十分了解。我已经花了数小时阅读(或浏览)了大量的教程和介绍以及StackOverflow问题,并且玩过wxFormBuilder,但我不觉得自己正在取得进步-我仍然对面板和大小和布局,以及哪些位应该属于哪些父级。

我认为,如果我能使这个最低版本正常工作,那么对我的真实应用程序将大有帮助。顶部的类似于工具栏的按钮似乎工作正常,但我想在下方的“显示”区域中使用最小(但可扩展)的垂直尺寸,居中的文本区域以及显示屏中的2-3个按钮行该文本下方的区域。该显示区域应根据上面按下的按钮进行更改和清除。这就是我所拥有的:

#!/usr/bin/env python3

import wx

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

        wx.Frame.__init__(self, parent, title=title, size=(-1,-1))

        # self.panel = wx.Panel(self, size=(-1,300))

        # buttons bar

        self.top_button_sizer = wx.BoxSizer(wx.HORIZONTAL)

        self.btn_left = wx.Button(self, -1, label="left")
        self.btn_right = wx.Button(self, -1, label="right")

        self.btn_left.Bind(wx.EVT_BUTTON, self.OnLeft)
        self.btn_right.Bind(wx.EVT_BUTTON, self.OnRight)

        self.top_button_sizer.Add(self.btn_left, 1, wx.EXPAND)
        self.top_button_sizer.Add(self.btn_right, 1, wx.EXPAND)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.display_sizer = wx.BoxSizer(wx.VERTICAL)
        self.text_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.display_text = wx.StaticText(self, label="Push a button!")
        self.display_buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.text_sizer.Add(self.display_text, 0, wx.ALIGN_CENTER, 5)
        self.display_sizer.Add(self.text_sizer, 1, wx.ALIGN_CENTER, 5)
        self.display_sizer.Add(self.display_buttons_sizer, 0, wx.EXPAND)

        self.sizer.Add(self.top_button_sizer, 0, wx.TOP | wx.EXPAND)
        # self.sizer.Add(self.panel)
        self.sizer.Add(self.display_sizer, 1, wx.EXPAND)

        self.SetSizerAndFit(self.sizer)
        self.Show()

    def OnLeft(self,e):
        # for child in self.display_buttons_sizer.GetChildren():
        #     child.Destroy()
        # ^ my attempt to "clear" causes a SegFault
        for child in self.display_buttons_sizer.GetChildren():
            child.Destroy()
        self.display_text.SetLabel("Hey lefty!")
        self.btn_hey = wx.Button(self, -1, label="Hey yourself lefty.")
        self.btn_whoa = wx.Button(self, -1, label="Whoa there lefty.")
        self.display_buttons_sizer.Add(self.btn_hey, 1, wx.EXPAND)
        self.display_buttons_sizer.Add(self.btn_whoa, 1, wx.EXPAND)

        self.sizer.Layout()

    def OnRight(self,e):
        # for child in self.display_buttons_sizer.GetChildren():
        #     child.Destroy()
        # ^ my attempt to "clear" causes a SegFault!
        self.display_text.SetLabel("Hey righty!")
        self.btn_hey = wx.Button(self, -1, label="Hey yourself righty.")
        self.btn_whoa = wx.Button(self, -1, label="Whoa there righty.")
        self.display_buttons_sizer.Add(self.btn_hey, 1, wx.EXPAND)
        self.display_buttons_sizer.Add(self.btn_whoa, 1, wx.EXPAND)

        self.sizer.Layout()

app = wx.App(False)
frame = MainWindow(None, "MWE")
app.MainLoop()

(我确信这在很多方面都是令人讨厌的代码。)我是否应该将面板放在某个地方?在哪里,如何?学习“笔记本”而不是使用顶部按钮会更容易吗?如何正确清除下面的“显示”区域中的内容,以便下次按下按钮?

奖励积分::实际应用中最复杂的顶部按钮是用于出席会议。它会显示多行文本(该班级的学生,我从sqlite获得;我认为那部分工作了),每行旁边都有用于显示/不存在的单选按钮,然后记录在数据库中。对此的提示也将不胜感激。

提前感谢您的耐心等候。

1 个答案:

答案 0 :(得分:0)

您可以通过几种不同的方式来做这种事情。您可以在按下按钮时交换面板,也可以只使用wx.Notebook,这基本上是相同的想法。我在这里写了一个有关面板切换的教程,对您可能会有所帮助:

它使用菜单而不是按钮,但这并不难更改。这是一个简单的示例,该示例不进行面板切换,但是显示了如何添加多行文本控件,该控件在按下按钮时会自动清除:

import wx

class MainPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
        btn_sizer = wx.BoxSizer(wx.HORIZONTAL)

        left_button = wx.Button(self, label='Left')
        left_button.Bind(wx.EVT_BUTTON, self.on_left)
        btn_sizer.Add(left_button, 0, wx.ALL, 5)

        right_button = wx.Button(self, label='Right')
        right_button.Bind(wx.EVT_BUTTON, self.on_right)
        btn_sizer.Add(right_button, 0, wx.ALL, 5)

        self.text_ctrl = wx.TextCtrl(self, style=wx.TE_MULTILINE)

        self.main_sizer.Add(btn_sizer, 0, wx.CENTER)
        self.main_sizer.Add(self.text_ctrl, 1, wx.ALL|wx.EXPAND, 5)
        self.SetSizer(self.main_sizer)

    def on_left(self, event):
        self.text_ctrl.Clear()
        self.text_ctrl.SetValue('Left')

    def on_right(self, event):
        self.text_ctrl.Clear()
        self.text_ctrl.SetValue('Right')



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

        wx.Frame.__init__(self, parent, title=title, size=(-1,-1))
        panel = MainPanel(self)
        self.Show()


app = wx.App(False)
frame = MainWindow(None, "MWE")
app.MainLoop()

这还演示了如何添加面板,建议您使用面板,因为面板可以在所有平台上为您提供正确的“外观”,并且还可以在控件之间进行制表。

通过使用此处显示的相同概念,您可以轻松地在底部添加另一组按钮,然后只需将第二组按钮的sizer添加到主sizer中即可。

如果您想使用某种单选按钮或选中按钮来处理文本行,我建议您使用wx.ListCtrl或(更好)ObjectListViewhttps://objectlistview-python-edition.readthedocs.io/en/latest/recipes.html#recipe-checkbox)(另请参见https://www.blog.pythonlibrary.org/2009/12/23/wxpython-using-objectlistview-instead-of-a-listctrl/

您可以将事件绑定到复选框,然后可以相应地更新数据库。