0

我是 python 语言的初学者,我正在尝试使用 wxpython 为我的程序制作一个简单的 gui。我的 gui 由一个框架和两个选项卡(使用 wxPanel)组成(选项卡 1 和选项卡 2)。我在选项卡 1 和选项卡 2 上都放置了 txtctrl 小部件。在选项卡 1 上,我放置了一个按钮,该按钮获取所有 txtctrl 值并将它们分配给相应的变量。我的问题是,我可以从选项卡 1 面板中的 txtctrls 获取值并将它们分配给选项卡 1 中的变量,但我无法从选项卡 2 面板中的 txtctrls 获取值并在选项卡 1 面板中使用它们(我想从选项卡 2 面板中获取值并将它们分配给选项卡 1 面板中的变量。)。你能帮我解决这个问题并运行我的代码吗?

我搜索了许多站点,阅读了框架或类之间数据传输的示例,并尝试应用它们,但仍然无法使其工作。

这是我的gui代码;

from wxPython.wx import *
import os

class PageOne(wxPanel):
    def __init__(self, parent):
        wxPanel.__init__(self, parent)
        self.SetBackgroundColour("gray")

        self.tc1=wxTextCtrl(self, -1, '',  (110, 15), (120, -1))
        self.tc2=wxTextCtrl(self, -1, '',  (110, 15), (120, -1))
        self.tc3=wxTextCtrl(self, -1, '',  (110, 15), (120, -1))
        self.st1=wxStaticText(self, -1, "input", pos=(10, 12))
        self.st2=wxStaticText(self, -1, "X:", pos=(10, 12))
        self.st3=wxStaticText(self, -1, "Y:", pos=(10, 12))
        self.st4=wxStaticText(self, -1, "Z:", pos=(10, 12))
        #flexgrid 
        self.fgs = wxFlexGridSizer(1, 7, 9, 10) 
        self.fgs.AddMany([(self.st1, 1, wxEXPAND),(self.st2, 1, \
        wxEXPAND),(self.tc1, 1,wxEXPAND),(self.st3, 1, wxEXPAND),\
        (self.tc2, 1, wxEXPAND),(self.st4, 1, wxEXPAND),(self.tc3, 1,\
        wxEXPAND)])
        # statik text 
        self.hsizer1 = wxBoxSizer(wxHORIZONTAL)
        self.hsizer2 = wxBoxSizer(wxHORIZONTAL)
        self.vsizerb = wxBoxSizer(wxVERTICAL)

        self.hsizer1.Add(self.fgs, 1, wxEXPAND |wxALIGN_CENTER| wxALL,1)

        self.but1=wxButton(self, 1, 'Calculate', (10, 10))
        self.but1.Bind(EVT_BUTTON, self.Create_OnClick)
        self.hsizer2.Add(self.but1, 1, wxALIGN_CENTER)

        self.vsizerb.Add(self.hsizer1, 1.8, wxEXPAND | wxALL, 10)
        self.vsizerb.Add(self.hsizer2, 0.2, wxEXPAND | wxALL, 10)
        self.SetSizer(self.vsizerb)

        self.PTWO=PageTwo(self)
        self.PTWO.Show()

    def Create_OnClick(self, event):
        text1=self.tc1.GetValue()
        text2=self.tc2.GetValue()
        text3=self.tc3.GetValue()
        #here I want to get pt2_1 value from tab2 panel and assign it
        #to text4 varibale.
        #on the gui, if you fill all txtcrtl boxes and press calculate 
        #button, it gives values of text3 and text4 on cmd.
        #I can get text3 value but cannot get text4 value.It gives null?
        text4=self.PTWO.pt2_1.GetValue()
        print "text_fromtab2:",text4,"text_fromtab1:",text3
        yer=os.getcwd()

class PageTwo(wxPanel):
    def __init__(self, parent):
        wxPanel.__init__(self, parent)
        self.SetBackgroundColour("gray")

        self.hsizerb = wxBoxSizer(wxHORIZONTAL)
        self.st5=wxStaticText(self, -1, "Input 1 (mm)", pos=(10, 12))
        # I want to be able to get these values from PageOne 
        self.pt2_1=wxTextCtrl(self, -1, '',  (110, 15), (120, -1))

        self.fgs_pt2 = wxFlexGridSizer(1, 2, 10, 10)   
        self.fgs_pt2.AddMany([(self.st5, 1, wxEXPAND),(self.pt2_1, 1,\
        wxEXPAND)])
        self.hsizerb.Add(self.fgs_pt2, 1, wxEXPAND |wxALIGN_CENTER| \
        wxALL, 10)
        self.SetSizer(self.hsizerb)

class MainFrame(wxFrame):
    def __init__(self, parent, fid, title):
        wxFrame.__init__(self, parent, fid, title, \
            pos = (200, 50), \
            size = (500, 200), \
            style = wxDEFAULT_FRAME_STYLE \
                |wxNO_FULL_REPAINT_ON_RESIZE)

        panel1 = wxPanel(self, -1)
        panel1.SetBackgroundColour("blue")

        nb = wxNotebook(panel1)
        page1 = PageOne(nb)
        page2 = PageTwo(nb)

        nb.AddPage(page1, "Tab 1")
        nb.AddPage(page2, "Tab 2")

        sizer = wxBoxSizer(wxVERTICAL)
        sizer.Add(nb, 1, wxALL|wxALIGN_CENTER|wxEXPAND, 1 )
        panel1.SetSizer(sizer)
        panel1.SetAutoLayout(True)
        self.Show(True)

if __name__ == "__main__":
        app = wxPySimpleApp()
        frame = MainFrame(None, wxID_ANY, "MY PROGRAM")
        app.MainLoop()
4

2 回答 2

0

当您已经在 MainFrame 中创建 PageTwo 时,您正在创建它两次

nb = wxNotebook(panel1)
page1 = PageOne(nb)
page2 = PageTwo(nb)

nb.AddPage(page1, "Tab 1")
nb.AddPage(page2, "Tab 2")

您不需要在 PageOne 中重新创建它,因此请删除它

self.PTWO=PageTwo(self)
self.PTWO.Show()

而是将 PageTwo 传递给 PageOne,例如

class PageOne(wxPanel):
    def __init__(self, parent, page2):
        wxPanel.__init__(self, parent)
        self.PTWO=page2

并在 MainFrame

nb = wxNotebook(panel1)
page2 = PageTwo(nb)
page1 = PageOne(nb, page2)

完成这些更改后,您应该能够正确访问 page2 中的值,但这表示您需要更多地考虑您要做什么?

  • 更好的方法是让页面将值保存到某些模型/对象,而其他页面可以访问该数据而不是直接访问 UI 元素,因为您可能需要在处理之前显示错误并清理数据,您可以在选项卡更改时执行此操作

  • 有更好的变量名而不是 text1 使用 self.textX 或 self.X 等

  • 您应该将计算功能分离到第三类,或者可能是大型机,page1 和 page2 应该只收集数据

于 2011-12-20T14:36:46.203 回答
0

你从哪里得到这样导入 wxPython 的想法?我很惊讶它甚至可以工作。你应该这样做:

import wx

你这样做的方式来自 wxPython 2.6 或更早版本,已经超过 5 年了。你真的不应该像那样从另一个屏幕中提取信息。您可以按照其他人提到的解决方法(即将第 2 页传递到第 1 页)执行此操作,也可以执行以下操作:

import wx
import os

class PageOne(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("gray")

        self.tc1=wx.TextCtrl(self, -1, '',  (110, 15), (120, -1))
        self.tc2=wx.TextCtrl(self, -1, '',  (110, 15), (120, -1))
        self.tc3=wx.TextCtrl(self, -1, '',  (110, 15), (120, -1))
        self.st1=wx.StaticText(self, -1, "input", pos=(10, 12))
        self.st2=wx.StaticText(self, -1, "X:", pos=(10, 12))
        self.st3=wx.StaticText(self, -1, "Y:", pos=(10, 12))
        self.st4=wx.StaticText(self, -1, "Z:", pos=(10, 12))
        #flexgrid 
        self.fgs = wx.FlexGridSizer(1, 7, 9, 10) 
        self.fgs.AddMany([(self.st1, 1, wx.EXPAND),
                          (self.st2, 1, wx.EXPAND),
                          (self.tc1, 1,wx.EXPAND),
                          (self.st3, 1, wx.EXPAND),
                          (self.tc2, 1, wx.EXPAND),
                          (self.st4, 1, wx.EXPAND),
                          (self.tc3, 1, wx.EXPAND)])
        # statik text 
        self.hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
        self.hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
        self.vsizerb = wx.BoxSizer(wx.VERTICAL)

        self.hsizer1.Add(self.fgs, 1, wx.EXPAND |wx.ALIGN_CENTER| wx.ALL,1)

        self.but1=wx.Button(self, 1, 'Calculate', (10, 10))
        self.but1.Bind(wx.EVT_BUTTON, self.Create_OnClick)
        self.hsizer2.Add(self.but1, 1, wx.ALIGN_CENTER)

        self.vsizerb.Add(self.hsizer1, 1.8, wx.EXPAND | wx.ALL, 10)
        self.vsizerb.Add(self.hsizer2, 0.2, wx.EXPAND | wx.ALL, 10)
        self.SetSizer(self.vsizerb)

    def Create_OnClick(self, event):
        text1=self.tc1.GetValue()
        text2=self.tc2.GetValue()
        text3=self.tc3.GetValue()
        #here I want to get pt2_1 value from tab2 panel and assign it
        #to text4 varibale.
        #on the gui, if you fill all txtcrtl boxes and press calculate 
        #button, it gives values of text3 and text4 on cmd.
        #I can get text3 value but cannot get text4 value.It gives null?
        notebook = self.GetParent()
        pageTwo = notebook.page2
        text4=pageTwo.pt2_1.GetValue()
        print "text_fromtab2:",text4,"text_fromtab1:",text3
        yer=os.getcwd()

class PageTwo(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("gray")

        self.hsizerb = wx.BoxSizer(wx.HORIZONTAL)
        self.st5=wx.StaticText(self, -1, "Input 1 (mm)", pos=(10, 12))
        # I want to be able to get these values from PageOne 
        self.pt2_1=wx.TextCtrl(self, -1, '',  (110, 15), (120, -1))

        self.fgs_pt2 = wx.FlexGridSizer(1, 2, 10, 10)   
        self.fgs_pt2.AddMany([(self.st5, 1, wx.EXPAND),
                              (self.pt2_1, 1, wx.EXPAND)])
        self.hsizerb.Add(self.fgs_pt2, 1, wx.EXPAND |wx.ALIGN_CENTER|wx.ALL, 10)
        self.SetSizer(self.hsizerb)

class MyNotebook(wx.Notebook):
    def __init__(self, parent):
        wx.Notebook.__init__(self, parent)
        self.page1 = PageOne(self)
        self.page2 = PageTwo(self)

        self.AddPage(self.page1, "Tab 1")
        self.AddPage(self.page2, "Tab 2")


class MainFrame(wx.Frame):
    def __init__(self, parent, fid, title):
        wx.Frame.__init__(self, parent, fid, title, \
            pos = (200, 50), \
            size = (500, 200), \
            style = wx.DEFAULT_FRAME_STYLE \
                |wx.NO_FULL_REPAINT_ON_RESIZE)

        panel1 = wx.Panel(self, -1)
        panel1.SetBackgroundColour("blue")

        nb = MyNotebook(panel1)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(nb, 1, wx.ALL|wx.ALIGN_CENTER|wx.EXPAND, 1 )
        panel1.SetSizer(sizer)
        panel1.SetAutoLayout(True)
        self.Show(True)

if __name__ == "__main__":
        app = wx.App(False)
        frame = MainFrame(None, wx.ID_ANY, "MY PROGRAM")
        app.MainLoop()

请注意 wx.PySimpleApp 现在已弃用,因此我将其换成了 wx.App(False)

就个人而言,我只是将所有数据输入内容放在一个屏幕上或将其保存到数据库或使用套接字服务器或使用 pubsub 传递数据(这将需要在第二页上发生某种事件,例如笔记本更改事件)。上面的代码是一个 hack,非常脆弱,但它确实有效。

于 2011-12-20T15:00:08.737 回答