0

I am trying to get an input from MyTCPHandler into the class Network in the following program. So Ideally I would like, for example, to take the self.data from MyTCPHandler and change the self._title in Network. As usual, I apologize for the simple question, but I am very new to classes in python and I am struggling a bit with this one. Thanks for your help!

from Tkinter import *
import time
import math
import lockfile
import functions
import SocketServer
import threading

class Network(Frame):  
    """ Implements a stop watch frame widget. """                                                               
    def __init__(self, parent=None, **kw):      
        Frame.__init__(self, parent, kw)

        HOST, PORT = "192.168.2.3", 9999
        self._server = SocketServer.TCPServer((HOST, PORT),MyTCPHandler)
        t = threading.Thread(target=self._server.serve_forever)
        t.setDaemon(True) 
        t.start()

        self._title="hello"
        self.makeWidgets()    

    def makeWidgets(self):                       
        """ Make the time label. """

        self._canvas = Canvas(self, width=600, height=400)
        self._canvas.pack()



class MyTCPHandler(SocketServer.BaseRequestHandler):
    """
    The RequestHandler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def handle(self):
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        print self.data
        #I want to set the above title to "self.data"        
        self.request.sendall(self.data.upper())




def main():
    root = Tk()

    #sw = StatusTable(root)
    #sw.pack(side=RIGHT)

    nw = Network(root)
    nw.pack(side=TOP)


    root.mainloop()


if __name__ == '__main__':
    main()

I am still struggling with this, my current code is below. I have two questions.
1. Ideally I would like to set the IP address insider the Network class, is this possible? 2. It appears that self._server does not have an attribute "_title", which is the one I am trying to pass from MyTCPHandler.

from Tkinter import *
import time
import math
import lockfile
import functions
import SocketServer
import threading


class Network(Tk):  
    def __init__(self,server):      
        Tk.__init__(self)

        self._server=server
        t = threading.Thread(target=self._server.serve_forever)
        t.setDaemon(True) # don't hang on exit
        t.start()

        self.makeWidgets()    

    def makeWidgets(self):                       
        """ Make the time label. """

        self._canvas = Canvas(self, width=600, height=400)
        self._canvas.pack()

        radius=20
        l = Label(self,text=self._server._title)
        l.pack(fill=X, expand=NO, pady=2, padx=2)   

class MyTCPHandler(SocketServer.BaseRequestHandler):
    def __init__(self):     
        self._title=StringVar()
        self._title="test"

    def handle(self):
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        print self.data
        self._title="change"
        print "changed?"
        # just send back the same data, but upper-cased
        self.request.sendall(self.data.upper())



def main():

    HOST, PORT = "10.0.1.08", 9999
    print HOST

    # Create the server, binding to localhost on port 9999
    server = SocketServer.TCPServer((HOST, PORT),MyTCPHandler)

    #sw = StatusTable(root)
    #sw.pack(side=RIGHT)

    nw = Network(server)
    nw.mainloop()
The-IT
  • 660
  • 8
  • 19
user1763510
  • 1,070
  • 1
  • 15
  • 28

1 Answers1

0

Since both classes are in the same process (and hence same memory space), why not just use a shared data. If you are worried about data being overwritten by threads, then you can add a lock on that data.

You could also consider making the second class an instance of the first one -- in that case, sharing data would be seamless. Here is a discussion, you might find useful: How to share data between two classes

Try this (you can remove the lock, if you have only one client and it is okay to be overwritten):

lock = threading.Lock()
data_title = ""

class Network(Tk):
    def __init__(self,server):
        Tk.__init__(self)

        self._server=server
        t = threading.Thread(target=self._server.serve_forever)
        t.setDaemon(True) # don't hang on exit
        t.start()

        self.makeWidgets()

    def makeWidgets(self):
        """ Make the time label. """
        print(dir(self._server))

        self._canvas = Canvas(self, width=600, height=400)
        self._canvas.pack()

        radius=20
        lock.acquire()
        l = Label(self,text=data_title)
        lock.release()
        l.pack(fill=X, expand=NO, pady=2, padx=2)

class MyTCPHandler(SocketServer.BaseRequestHandler):
    def __init__(self):
        self._title=StringVar()
        self._title="test"

    def handle(self):
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        print self.data
        lock.acquire()
        self._title="change"
        lock.release()
        print "changed?"
        # just send back the same data, but upper-cased
        self.request.sendall(self.data.upper())
Community
  • 1
  • 1
Manoj Pandey
  • 4,528
  • 1
  • 17
  • 18
  • This sounds fine. Is there a specific shared data module, or is this built in? – user1763510 Sep 03 '13 at 21:47
  • You can just define data as a global variable. If you have multiple threads, you can use the lock provided by the threading module. – Manoj Pandey Sep 03 '13 at 21:51
  • For IP address (HOST in your code), you should use the IP address used by the server. If you don't know and would be running this code at the server, then simply leave it as an emtpy string: HOST = "". – Manoj Pandey Sep 03 '13 at 23:26
  • You can use print(dir(self._server)) to print all the methods/attributes available with the self._server. If it does not have '_title', then well, you cannot use it. Why are you trying to use an attribute that does not exist? – Manoj Pandey Sep 03 '13 at 23:29
  • I want the title to be set in the class MyTCPHandler and then passed to the class Network. I currently set _title in MyTCPHandler, but still don't know how to get it to Network – user1763510 Sep 03 '13 at 23:31
  • Thanks for all the help. I am still having trouble with the global variable approach as I need the variable to be a Tkinter.StringVar() object. I will keep messing around. I think in need to explore the MyTCPHandler class more. – user1763510 Sep 04 '13 at 00:11