1

I'm trying to make an infinite loop (with a break) that runs alongside my Tkinter window and interacts with widgets on it. Yes, I have done my research, but when I run my code and activate the function the window stops responding.

I've deleted the 'while true' from the method, and at the end of it placed:

if self.connected:
    root.after(100, self.listenServer(id, req))

I think the problem is that the function takes a little while to complete (I'm making an Omegle client, so it has to connect to the server). I can tell that it runs six times, because I put a print statement in the method.

Is there a simple (AKA no threading) method to solve this problem?

Well, if threading is the only way to do it, then I guess it would be fine

Here are my connect and listen methods:

    def listenServer(self, id, req):
    site = url.urlopen(req)

    #We read the HTTP output to get what's going on
    rec = site.read()

    if 'waiting' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Waiting...\n", "italic")
        self.chatbox.config(state=DISABLED)

    elif 'connected' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Stranger connected\n", "italic")
        self.chatbox.config(state=DISABLED)

    elif 'strangerDisconnected' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Stranger Disconnected\n", "italic")
        self.chatbox.config(state=DISABLED)
        self.connected = False

    elif 'typing' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Stranger is typing\n", "italic")
        self.chatbox.config(state=DISABLED)

    elif 'gotMessage' in rec:
        self.chatbox.config(state=NORMAL)
        self.chatbox.insert(END, "Stranger: " + rec[17:len(rec) - 3] + "\n")
        self.chatbox.config(state=DISABLED)

def OmegleConnect(self):
    self.chatbox.config(state=NORMAL)
    self.chatbox.insert(END, "Connecting...\n", "italic")
    self.chatbox.config(state=DISABLED)

    site = url.urlopen('http://omegle.com/start', '')
    id = site.read()
    id = id[1:len(id) - 1]
    self.chatbox.config(state=NORMAL)
    self.chatbox.insert(END, "Stranger ID: " + id + "\n", "title")
    self.chatbox.config(state=DISABLED)
    req = url.Request('http://omegle.com/events', urllib.urlencode({'id':id}))
    self.chatbox.config(state=NORMAL)
    self.chatbox.insert(END, "Finding a stranger...\n", "italic")
    self.chatbox.config(state=DISABLED)
    self.connected = True
    root.after(100, self.listenServer(id, req))

Yes, I know this is quite inefficient with the way it writes to the text widget. I tried making a method to do it more easily, but it wasn't working. I'll worry about that once I get this up and running.

2
  • Are you asking for a solution that utilises threading now? If so, we are going to need to see more code and know what you are trying to do. Commented May 5, 2012 at 15:15
  • Yes, if that's what has to be done Commented May 5, 2012 at 15:16

2 Answers 2

2

The issue here is that the window needs to be continuously updating in order for the window to react to input - that's a reality of the way the program works, and makes sense.

On the other hand, you want to do something in a loop which doesn't allow the window to update - given this, there is no way for the window to react.

So no, there is no solution to this that won't involve threading or multiprocessing in some way - you need to do two things at once.

Possible solutions:

If you don't want to deal with threading directly, you could use a library like twisted to provide the networking you are talking about, which will avoid you waiting on your request to complete.

The other main option is to use the multiprocessing module or threading module to move the things you want to do simultaneously to updating your interface into a new thread/process.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm looking at the multiprocessing module, and I've decided there will be a separate method that is run every so often using Tkinter's 'after' that will communicate with listenServer.
0

if you do not want to use threading:

tkinterwidget.update() # repaint & use events

or if you want to schedule something:

class MainWindo(Tk):

    ...

    def method(self):
        # do something here for every 100 ms
        if loop:
            self.after(100, self.method)

Be careful not to interact with Tkinter from two threads. My Programs sometimes crashed because of this.

1 Comment

Did you read my entire post? I tried 'after' but since the method takes a while, my program freezes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.