How to 're-run' the mainloop in Tkinter - python-2.7

I've been asked to make a Chat program using Tkinter. For the final part, I'm supposed to have the Chat window open, which has one Entry field, one Button (SEND) and a Text Widget to display the chat log. This is my first week learning Tkinter, and I've been told in class that the mainloop() is an infinite loop as long as the user doesn't close the window or write root.quit(). So in the chat window, I'm supposed to check for new messages every 10 seconds. Is it possible to do that in the mainloop()? If yes, please let me know how, because I have no idea how that can happen since the stuff before the mainloop() is read only once. For example, something like a print statement is printed only once, even though the mainloop() is an infinite loop.

You can call the after method of the root window to call something in the future. If that function itself calls after, you can set it up so that your function runs every 10 seconds forever.
def check_for_messages():
<your code here>
root.after(10000, check_for_messages)
Call that function once before calling mainloop() and it will run every 10 seconds for as long as mainloop() is running.

Related

CPP, 'X' button listener

I'm writing a CPP program, and I want to execute a function when the 'X'(shut down) button is pressed.
For example, I have an infinite loop that prints the same thing everytime it iterates, until the 'X' button is pressed, and I want to execute a function before the process ends.
Is there some kind of listener for this matter? Or some other solution maybe (like delaying the process shut down for a few seconds or something)?
Thanks!
If you want to execute something before your process ends, you can register an std::atexit handler. This function will be called before your process exits.

SendMessage WM_COPYDATA between two processes [duplicate]

Basically exactly what the title says. I would like to update the text that a button contains every 1 second when the user presses that particular button. I have noted that when the program doesn't have focus it works alright and the text refreshes correctly but when I am hovering over the program or when I am trying to click on it's menu Windows inform me that the program is unresponsive and asks me if I want it terminated. When the loop finishes the program returns to its normal state. Also any action I might have done (like moving it around or closing it) while it was Sleep()-ing is executed after the loop. Here is a bit of code:
case ID_BUTTON_START:
// Code executed when pressing Start Button.
char startButtonText[30]; // Storing next loop text
for (int i=5; i>0; i--)
{
sprintf(startButtonText, "Starting in ... %d", i);
SendMessage(hwndButtonStart, WM_SETTEXT, 0, (LPARAM)(startButtonText));
Sleep(1000);
}
Is this normal? If not what's causing this?
The WndProc does not process messages asynchronously within an application which means all messages are expected to be handled quickly and a return value delivered immediately. You must not Sleep in the UI thread since it will block other UI events from being processed. Any heavy work or synchronous requests/jobs which are likely to take a long time should be performed in worker threads. There are at least three viable options:
Create a new (worker thread) for the task.
If the task is likely to be done often, use a thread pool instead.
Set and subscribe to timer events.
I think the call to Sleep() might be keeping you from returning from the WndProc, so your application is not processing the incomming events for 5 secs. I suggest you try to subscribe to 5 timer events in 1s, 2s,..., 5s. Like when the timer message is recieved the button text must change. I don't know a way how to do that off the top of my head.

Windows phone C++

I'm writing simple application for WP 8.1 using C++/cx. My problem starts when I'm trying to do something in some event. For example if I create simple button event "tapped" and I want to do something inside for example change the color of the button background, it doesn't execute in the correct time. I mean that for the code below it will first execute Somefunction() and then change the color of the button.Same happens for example when I try to show message box using message dialog and ShowAsync function.
but->Background = ref new SolidColorBrush(Windows::UI::Colors::Red);
Somefunciton();
You have the background change and the function call in the same function and that function gets executed on one thread blocking it. This thread happens to be the UI thread which gets blocked for the time of your function execution. So you set the button background but the actual change will be applied only when the UI thread could run the render function and it will be able to do it only after your function call ends.
So in terms of program execution the button background gets updated before the call to Somefunciton();. But visual changes are delayed until after the function call is completed so you might think that Somefunciton(); gets called before the background is set which is not the case.

Preventing PySide from Outrunning Python

I have a PySide application that connects a number of buttons to a function call that spins off a bunch of external processes (this isn't ideal, but it is necessary).
The function call takes less than a quarter of a second to run, but it still presents a chance for the user to outrun my code, causing lag, freezing, or crashing.
This leads me to a few questions...
What exactly does it mean for a callable to be connected to a signal? Suppose button A's click signal is connected a Python function f. If A is clicked, and then clicked again before f exits, does PySide simply queue another call to f, or does it do something fancier?
One possible solution is to make f disconnect itself from the signal and then reconnect before it exits. Before I go off rewriting things to try this, does anyone know if this is at all efficient, or if there is a more elegant solution?
I'm guessing it does exactly what every other GUI toolkit does, which is try to execute that function for every button press. If you don't want that, then there are several approaches you can take:
Disable the button until the function finishes
Use a sentinel value, like self.running, and add a check to see if it is True. If so, return. Otherwise, set it to True and execute. Just remember to set it back to False at the end of the function
Do what you mentioned and disconnect the function from the signal
Those are the main ones. I'm sure there are some more esoteric solutions out there too though.

Sleep() in Win32 makes program unresponsive

Basically exactly what the title says. I would like to update the text that a button contains every 1 second when the user presses that particular button. I have noted that when the program doesn't have focus it works alright and the text refreshes correctly but when I am hovering over the program or when I am trying to click on it's menu Windows inform me that the program is unresponsive and asks me if I want it terminated. When the loop finishes the program returns to its normal state. Also any action I might have done (like moving it around or closing it) while it was Sleep()-ing is executed after the loop. Here is a bit of code:
case ID_BUTTON_START:
// Code executed when pressing Start Button.
char startButtonText[30]; // Storing next loop text
for (int i=5; i>0; i--)
{
sprintf(startButtonText, "Starting in ... %d", i);
SendMessage(hwndButtonStart, WM_SETTEXT, 0, (LPARAM)(startButtonText));
Sleep(1000);
}
Is this normal? If not what's causing this?
The WndProc does not process messages asynchronously within an application which means all messages are expected to be handled quickly and a return value delivered immediately. You must not Sleep in the UI thread since it will block other UI events from being processed. Any heavy work or synchronous requests/jobs which are likely to take a long time should be performed in worker threads. There are at least three viable options:
Create a new (worker thread) for the task.
If the task is likely to be done often, use a thread pool instead.
Set and subscribe to timer events.
I think the call to Sleep() might be keeping you from returning from the WndProc, so your application is not processing the incomming events for 5 secs. I suggest you try to subscribe to 5 timer events in 1s, 2s,..., 5s. Like when the timer message is recieved the button text must change. I don't know a way how to do that off the top of my head.