对于如何构建GUI界面(wxpython),感到困惑了吗?

3
我已经阅读了各种书籍和谷歌搜索结果,注意到每一本书都以完全不同的方式启动主窗口。我不想养成坏习惯,所以请问有人能给我推荐最好的选项及其原因吗?以下是我见过的所有方法:
A) class iFrame(wx.Frame): def __init__(....): wx.Frame.__init__(...)
B) class iFrame(wx.Frame): def __init__(...): super().__init__(...)
C) 然后我看到一些使用 Panel 的例子,如: class iPanel(wx.Panel) def __init__(...): wx.Panel.__init__(...)
D) 更令人困惑的是,有些人使用 wx 的常规 App 类,例如: class iApp(wx.App): def OnInit(self): wx.Frame.__init__(...)
请问,这些结构中哪一个是最好的 GUI 结构,如果有的话?当他们都以不同的方式进行操作时,跟随教程和书籍变得很困难。
4个回答

3

我最喜欢开始wx应用程序开发的方式是:

import wx

class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.panel = wx.Panel(self)
        self.button = wx.Button(self.panel, label="Test")

        self.sizer = wx.BoxSizer()
        self.sizer.Add(self.button)

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

app = wx.App(False)
win = MainWindow(None)
app.MainLoop()

请查看相关的这个问题

3

不要担心,你现在做出的选择不会毁掉你未来的编程之路。

你提到的选项都不是错误的。它们之间的差异是因为不同的应用有不同的要求。没有一种方法是最好的。

只需专注于自己想要的并采用适合自己的方法,等到更加熟悉后,你就会明白为什么不同的代码会有所不同。


2
我已经深刻认识到,无论在哪个应用程序中,封装都是非常重要的。对于wxPython来说,主框架对象应该有一个面板小部件,加上可选的菜单栏、工具栏和状态栏小部件。不要添加其他任何东西。
这是我创建新的wxPython应用程序的基本模式:
(更新于2019年2月7日:Wx Phoenix和Python 3)
import wx


class MainFrame(wx.Frame):
    """Create MainFrame class."""
    def __init__(self, *args, **kwargs):
        super(MainFrame, self).__init__(None, *args, **kwargs)
        self.Title = 'Basic wxPython module'
        self.SetMenuBar(MenuBar(self))
        self.ToolBar = MainToolbar(self)
        self.status_bar = StatusBar(self).status_bar
        self.Bind(wx.EVT_CLOSE, self.on_quit_click)
        panel = MainPanel(self)
        sizer = wx.BoxSizer()
        sizer.Add(panel)
        self.SetSizerAndFit(sizer)
        self.Centre()
        self.Show()

    def on_quit_click(self, event):
        """Handle close event."""
        del event
        wx.CallAfter(self.Destroy)


class MainPanel(wx.Panel):
    """Panel class to contain frame widgets."""
    def __init__(self, parent, *args, **kwargs):
        super(MainPanel, self).__init__(parent, *args, **kwargs)

        """Create and populate main sizer."""
        sizer = wx.BoxSizer(wx.VERTICAL)
        cmd_quit = wx.Button(self, id=wx.ID_EXIT)
        cmd_quit.Bind(wx.EVT_BUTTON, parent.on_quit_click)
        sizer.Add(cmd_quit)
        self.SetSizer(sizer)


class MenuBar(wx.MenuBar):
    """Create the menu bar."""
    def __init__(self, parent, *args, **kwargs):
        super(MenuBar, self).__init__(*args, **kwargs)
        # File menu
        file_menu = wx.Menu()
        self.Append(file_menu, '&File')

        quit_menu_item = wx.MenuItem(file_menu, wx.ID_EXIT)
        parent.Bind(wx.EVT_MENU, parent.on_quit_click, id=wx.ID_EXIT)

        file_menu.Append(quit_menu_item)


class MainToolbar(wx.ToolBar):
    """Create tool bar."""
    def __init__(self, parent, *args, **kwargs):
        super(MainToolbar, self).__init__(parent, *args, **kwargs)

        #quit_bmp =  wx.ArtProvider.GetBitmap(wx.ART_QUIT)
        #self.AddTool(wx.ID_EXIT, 'Quit', wx.Bitmap(quit_bmp))
        #self.SetToolShortHelp(wx.ID_EXIT, 'Quit')
        #self.Bind(wx.EVT_TOOL, parent.on_quit_click, id=wx.ID_EXIT)
        #self.Realize()


class StatusBar(object):
    def __init__(self, parent):
        """Create status bar."""
        self.status_bar = parent.CreateStatusBar()


if __name__ == '__main__':
    """Run the application."""
    screen_app = wx.App()
    main_frame = MainFrame()
    screen_app.MainLoop()

这正是我长期以来一直在寻找的东西。非常感谢您。 - user8396116
除了这个,你如何将它组织成文件? - user8396116
这要看情况。对于小型应用程序,可以全部放在一个文件中。对于大型应用程序,可能需要将框架放在一个文件中,面板放在另一个文件中,菜单和工具栏放在第三个文件中(也许)。由你自己选择。(这是你想要的吗?) - Psionman
这部分是我想要的。但是,你如何为一个大型应用程序导入菜单和工具栏呢?我已经尝试过了,但没有成功。 - user8396116
@XilyummY 我添加了一个新答案,其中主要类定义在单独的文件中。 - Psionman

1
作为对XilyummY评论的回应,我添加了这个额外的答案来展示如何将主要类组织到不同的文件中。
这是基于四个文件的解决方案:
  1. main.py:应用程序的主框架和应用程序加载器;
  2. main_panel.py:应用程序的主面板;
  3. menu_bar.py:框架的菜单栏定义;
  4. tool_bar.py:来自框架的工具栏。
代码按照以下顺序进行:

main.py

import wx

from main_panel import MainPanel
from menu_bar import MenuBar
from tool_bar import MainToolbar


class MainFrame(wx.Frame):
    """Create MainFrame class."""
    def __init__(self, *args, **kwargs):
        super(MainFrame, self).__init__(None, *args, **kwargs)
        self.Title = 'Basic wxPython module'
        self.SetMenuBar(MenuBar(self))
        self.ToolBar = MainToolbar(self)
        self.status_bar = StatusBar(self).status_bar
        self.Bind(wx.EVT_CLOSE, self.on_quit_click)
        panel = MainPanel(self)
        sizer = wx.BoxSizer()
        sizer.Add(panel)
        self.SetSizerAndFit(sizer)
        self.Centre()
        self.Show()

    def on_quit_click(self, event):
        """Handle close event."""
        del event
        wx.CallAfter(self.Destroy)


class StatusBar(object):
    def __init__(self, parent):
        """Create status bar."""
        self.status_bar = parent.CreateStatusBar()


if __name__ == '__main__':
    """Run the application."""
    screen_app = wx.App()
    main_frame = MainFrame()
    screen_app.MainLoop()

main_panel.py

import wx


class MainPanel(wx.Panel):
    """Panel class to contain frame widgets."""
    def __init__(self, parent, *args, **kwargs):
        super(MainPanel, self).__init__(parent, *args, **kwargs)

        """Create and populate main sizer."""
        sizer = wx.BoxSizer(wx.VERTICAL)
        cmd_quit = wx.Button(self, id=wx.ID_EXIT)
        cmd_quit.Bind(wx.EVT_BUTTON, parent.on_quit_click)
        sizer.Add(cmd_quit)
        self.SetSizer(sizer)

menu_bar.py

import wx


class MenuBar(wx.MenuBar):
    """Create the menu bar."""
    def __init__(self, parent, *args, **kwargs):
        super(MenuBar, self).__init__(*args, **kwargs)
        # File menu
        file_menu = wx.Menu()
        self.Append(file_menu, '&File')

        quit_menu_item = wx.MenuItem(file_menu, wx.ID_EXIT)
        parent.Bind(wx.EVT_MENU, parent.on_quit_click, id=wx.ID_EXIT)

        file_menu.Append(quit_menu_item)

tool_bar.py

import wx


class MainToolbar(wx.ToolBar):
    """Create tool bar."""
    def __init__(self, parent, *args, **kwargs):
        super(MainToolbar, self).__init__(parent, *args, **kwargs)

        new_bmp =  wx.ArtProvider.GetBitmap(wx.ART_NEW)
        #preferences_bmp = wx.Bitmap('images/preferences.png')
        quit_bmp =  wx.ArtProvider.GetBitmap(wx.ART_QUIT)

        self.AddTool(wx.ID_NEW, 'New', new_bmp)
        #self.AddTool(wx.ID_PREFERENCES, 'Preferences', preferences_bmp)
        self.AddTool(wx.ID_EXIT, 'Quit', quit_bmp)

        self.SetToolShortHelp(wx.ID_NEW, 'New ...')
        self.SetToolShortHelp(wx.ID_PREFERENCES, 'Preferences ...')
        self.SetToolShortHelp(wx.ID_EXIT, 'Quit')

        self.Bind(wx.EVT_TOOL, parent.on_quit_click, id=wx.ID_EXIT)

        self.Realize()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接