0

私は Python 言語の初心者で、wxpython を使用して自分のプログラム用の簡単な GUI を作成しようとしています。私の GUI は、フレームとその上の 2 つのタブ (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

You are creating PageTwo twice, when you have already created it in MainFrame

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

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

you don't need to recreate it in PageOne, so remove this

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

Instead pass PageTwo to PageOne e.g.

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

and in MainFrame

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

Once you have done these changes you should be able to access values from page2 correctly, but that said you need to think more about what are you trying to do?

  • Better way would be to let pages save values to some model/object and other pages can access that data instead of directly accessing UI elements, because you may need to show error and clean data before processing anyway, you can do that on tab change

  • Have better variable names instead of text1 use self.textX or self.X etc

  • You should separate out calculation function to a third class or may be Mainframe, page1 and page2 should only collect data

于 2011-12-20T14:36:46.203 に答える
0

そのように wxPython をインポートするというアイデアはどこから得たのですか? 私はそれがうまくいくことに驚いています。次のようにする必要があります。

import wx

あなたがやっている方法は、5年以上前のwxPython 2.6以前のものです。そのような他の画面から情報を引き出すべきではありません。回避策として言及されている他の仲間のようにすることができます(つまり、ページ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) に置き換えました。

個人的には、すべてのデータ入力項目を 1 つの画面に配置するか、データベースに保存するか、ソケット サーバーを使用するか、pubsub を使用してデータを渡します (これには、ノートブックなどの 2 ページ目で何らかのイベントが発生する必要があります)。イベントを変更します)。上記のコードはハックであり、かなり脆弱ですが、機能します。

于 2011-12-20T15:00:08.737 に答える