点击按钮,面板两个字段的数据应该复制到面板一个字段?

时间:2011-12-19 22:58:09

标签: python wxpython panels

我是python语言的初学者,我正在尝试使用wxpython为我的程序创建一个简单的gui。我的gui由一个框架和两个标签(使用wxPanel)组成(标签1和标签2)。我在选项卡1和选项卡2上放置了txtctrl小部件。在选项卡1上,我放置了一个按钮,它获取所有txtctrl值并将它们分配给相应的变量。我的问题是,我可以从txtctrls获取放在选项卡1面板中的值,并将它们分配给选项卡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()

2 个答案:

答案 0 :(得分: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)

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

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

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

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

答案 1 :(得分: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并且相当脆弱,但它 工作。