Hello All,
Greetings!
I have question concerning OOP with Python. I want to know when Python class or being specific, how py class ends in package like wxpython.

What I mean is I have one class let say of frame and another class of a dialog box all in same py file. When Frame runs, uses self i.e self.button = wx.Button. This object belongs to frame. And let say we have text control in the other class (dialog). How do I call method of another class from the other class, i.e how do I call button from dialog and dialog from button.

Suppose I want to manipulate the button, let say its label, but from another class which it doesn't belong (In this case Dialog)?

I hhave done these without grasp thge real concept. I have dug up but I find difficult to grasp it wel; so, need your support!

Recommended Answers

All 9 Replies

Maybe this short example will help:

# reference across class instances
# from one panel class to another panel class

import wx
import time

class MyPanel1(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY,
            pos=(0,0), size=(300, 100))
        self.SetBackgroundColour("green")
        self.button = wx.Button(self, label=" panel1 button ")
        self.button.Bind(wx.EVT_BUTTON, self.buttonClick )

    def buttonClick(self, event):
        """
        use the panel2 label and
        reference via the parent --> frame
        """
        #  display something that indicates a change
        s = time.strftime("%H:%M:%S", time.localtime())
        frame.panel2.label.SetLabel(s)


class MyPanel2(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY,
            pos=(0, 100), size=(300, 100))
        self.SetBackgroundColour("yellow")
        self.label = wx.StaticText(self, wx.ID_ANY, " panel2 label ")


app = wx.App(0)
# create a frame, no parent, default ID, title, size
caption = "wx.Panel()"
frame = wx.Frame(None, wx.ID_ANY, caption, size=(300, 220))

# note that frame is the parent for the two panels
frame.panel1 = MyPanel1(frame)
frame.panel2 = MyPanel2(frame)

frame.Show(True)
app.MainLoop()

Ene, you are using global instances, so the frame.panel1 or frame.panel2 reference is actually not needed. You can just use panel1 and panel2. However, your approach keeps things together.

hello Ene, Vega and All Daniweb,
Please assist me on how calling is done on this line:

frame.panel2.label.SetLabel(s)

Does it change the label of

self.label = wx.StaticText(self, wx.ID_ANY, " panel2 label ")

????

What are you really doing with this line of codes? Are you appending them to table??
I ask because I have never used before this such way of coding in py
[

frame.panel1 = MyPanel1(frame)
frame.panel2 = MyPanel2(frame)

Thanks for your answers

Yes, in Ene's code she references
self.label = wx.StaticText(self, wx.ID_ANY, " panel2 label ")
created in panel2 with
frame.panel2.label.SetLabel(s)
used in panel1

The trick here is to create the instances for both panels in __main__ to make them globally available.

If you don't want to use global instances, then you can let the parent carry the connection ...

# reference across class instances
# from one panel class to another panel class
# via common parent

import wx
import time

class MyFrame(wx.Frame):
    def __init__(self, parent, mytitle, mysize):
        wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle, size=mysize)

        # here panel1 and panel2 are local
        # but can be accessed via the parent
        self.panel1 = MyPanel1(parent=self)
        self.panel2 = MyPanel2(parent=self)


class MyPanel1(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY,
            pos=(0,0), size=(300, 100))
        # parent is common to both panels and
        # in this case cross references the panels
        self.parent = parent
        self.SetBackgroundColour("green")
        self.button = wx.Button(self, label=" panel1 button ")
        self.button.Bind(wx.EVT_BUTTON, self.buttonClick )

    def buttonClick(self, event):
        """
        use the panel2 label and
        reference via the parent --> frame
        """
        #  display something that indicates a change
        s = time.strftime("%H:%M:%S", time.localtime())
        # parent, or in this case self.parent, allows you to
        # get to widgets created in panel2
        self.parent.panel2.label.SetLabel(s)


class MyPanel2(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY,
            pos=(0, 100), size=(300, 100))
        self.SetBackgroundColour("yellow")
        self.label = wx.StaticText(self, wx.ID_ANY, " panel2 label ")


app = wx.App(0)
# create a frame parent=None, title, size
mytitle = "cross reference via common parent"
MyFrame(None, mytitle, (300, 220)).Show(True)
app.MainLoop()

This is IMHO a little cleaner and safer. No offence Ene!

code is self explanatory. However I have to be sure that I grasped the concept and then go for practice:

self.parent.panel2.label.SetLabel(s)

suppose I have two dialog boxes and both have parent called frm and dialogs dia1 and dia2
dia1 a button, and dia2 a button. The dialog1 appears automatically after some time (that is easy to do) and when you press the button it calls dialog2 and get destroyed. I need its theory and even veeery simple example and the rest is my exercise!

Sorry for bothering and thanks for response!
Steve

At this point you better give us some code, or we all get lost.

#call dialog, type new caption, set it to static text and destroy the dialog
import wx
class Main(wx.Frame):
	def __init__ (self, parent, id, title):
		wx.Frame.__init__(self, parent, id, title)
		panel = wx.Panel(self, -1)
		#Make button
		bu = wx.Button(panel, -1, "Call")
		self.Bind(wx.EVT_BUTTON, self.OnCall, id=bu.GetId())
		#create static text ctrl
		title = wx.StaticText(panel,-1, "Original Text", style=wx.ALIGN_LEFT)
		#Add to sizer
		sizer = wx.BoxSizer(wx.VERTICAL)
		sizer.Add(title, 1, wx.EXPAND |wx.ALL, 10)
		sizer.Add(bu, 0, wx.ALL, 10)
		panel.SetSizer(sizer)
		panel.Layout()
		
	def OnCall(self, event):
		dialog = Dialog(self, -1, "Change caption")
		dialog.Show(True)
		Main.Hide()
		
#Dialog box as another class
class Dialog(wx.Dialog):
	def __init__(self,  parent, id, title):
		wx.Dialog.__init__(self, parent, id, title)
		self.text = wx.TextCtrl(self, -1)
		ok = wx.Button(self, -1, "Ok")
		#Bind to event tochange caption of Title=text
		self.Bind(self, wx.EVT_BUTTON, self.OnChangeCaption, id = ok.GetId())
		sizer2 = wx.BoxSizer()
		sizer2.Add(self.text, 1, wx.EXPAND |wx.ALL, 10)
		sizer2.Add(ok, 0, wx.ALL, 10)
		self.SetSizer(sizer2)
		self.Layout()		
		
	def OnChangeCaption(self, event):
		newlabel = self.text.GetValue()
		self.title.SetLabel(newlabel)

app = wx.App(False)
f = Main(None, -1, "Call Children from parent")
f.Show(True)
app.MainLoop()

So what is your error?

when i click call button I get:

Traceback (most recent call last):
File "C:\Users\Elijah Ministries\Documents\NetBeansProjects\Learning Python\src\database - Griboullis.py", line 20, in OnCall
dialog = Dialog(self, -1, "Change caption")
File "C:\Users\Elijah Ministries\Documents\NetBeansProjects\Learning Python\src\database - Griboullis.py", line 31, in __init__
self.Bind(self, wx.EVT_BUTTON, self.OnChangeCaption, id = ok.GetId())
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 3885, in Bind
id = source.GetId()
AttributeError: 'function' object has no attribute 'GetId'

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.