Threading with PyGTK - python

To begin, I must say that I have searched for quite a long time on this subject and I probably know of most basic resources. I am attempting to use this: https://github.com/woodenbrick/gtkPopupNotify to add a system of notifications to a previously all command line program. Sadly, this usually will hang due to the fact that I perform lots of sleep operations, etc. I would assume it would work if I could get a system of threading in place. Essentially, all I want is to make a notification that doesn't interfere with any other operations of the program including other PyGTK components. Functions to make these notifications at the moment are looking like this for me:
def showMessage(title, message):
notifier1 = gtkPopupNotify.NotificationStack(timeout=4)
notifier1.bg_color = gtk.gdk.Color("black")
notifier1.fg_color = gtk.gdk.Color("white")
notifier1.edge_offset_x = 5-27 #-27 for odd bugginess
notifier1.edge_offset_y = 5
notifier1.new_popup(title=title, message=message)
Any help would be greatly appreciated as I am becoming really fed up with this problem.

With PyGTK, I highly recommend avoiding threads altogether. The GTK libraries aren't fully thread-safe and, under Win-32, they don't support threads at all. So, trying to work with them ends up being a pain. You can get some really nice results by "faking it" using Python generators and the gobject.idle_add() method
As an alternative to coding it yourself, you can also just use Zenity, which is a Gnome program for launching notification dialogs from the command line. This should be thread-safe.
import subprocess
subprocess.call(["zenity", "--notification", "--text=You have been notified"])

Related

Looking for a way to check for unexpected windows during a for loop in python automated testing

I am running some automated tests on an POS application where a large number of sales are entered using a for loop. During the test there are times where it is possible for the application window to lose focus, and when this happened we get a pop up window and this causes the test to stop.
I currently have a lot of checks in the code to look for this window after multiple steps in the loop, but each one I add adds time to the sale and slows the test down. Is there a way in python to constantly check for something like these windows.
To note I am using TestComplete and I have looked into the event handlers and it does not appear I will be able to use them due to how the application was developed.
I recommend you try to use an interrupt schedule. The basic idea is that you trigger a function (in this case your function checking for unexpected windows) whenever some counter reaches a value.
If you don't need to check at very specific and short time intervals it is enough to use something like time.clock(). I you DO need the abovementioned there are libraries for that, specifically the signal module or the more advanced sched, which are both part of the standard library (as far as I know, Documentation of signal, Documentation of sched).
There are also other (external, non-standard) modules that can work, but sched and/or signal should be enough here.
Feel free to ask if any further question should arise.
This SO post might also help: real time interrupts in python

Python Save Sets To File On Windows Shutdown?

I do not want to lose my sets if windows is about to shutdown/restart/log off/sleep, Is it possible to save it before shutdown? Or is there an alternative to save information without worring it will get lost on windows shutdown? JSON, CSV, DB? Anything?
s = {1,2,3,4}
with open("s.pick","wb") as f: # pickle it to file when PC about to shutdown to save information
pickle.dump(s,f)
I do not want to lose my sets if windows is about to shutdown/restart/log off/sleep, Is it possible to save it before shutdown?
Yes, if you've built an app with a message loop, you can receive the WM_QUERYENDSESSION message. If you want to have a GUI, most GUI libraries will probably wrap this up in their own way. If you don't need a GUI, your simplest solution is probably to use PyWin32. Somewhere in the docs there's a tutorial on creating a hidden window and writing a simple message loop. Just do that on the main thread, and do your real work on a background thread, and signal your background thread when a WM_QUERYENDSESSION message comes in.
Or, much more simply, as Evgeny Prokurat suggests, just use SetConsoleCtrlHandler (again through PyWin32). This can also catch ^C, ^BREAK, and the user closing your console, as well as the logoff and shutdown messages that WM_QUERYENDSESSION catches. More importantly, it doesn't require a message loop, so if you don't have any other need for one, it's a lot simpler.
Or is there an alternative to save information without worring it will get lost on windows shutdown? JSON, CSV, DB? Anything?
The file format isn't going to magically solve anything. However, a database could have two advantages.
First, you can reduce the problem by writing as often as possible. But with most file formats, that means rewriting the whole file as often as possible, which will be very slow. The solution is to streaming to a simpler "journal" file, packing that into the real file less often, and looking for a leftover journal at every launch. You can do that manually, but a database will usually do that for you automatically.
Second, if you get killed in the middle of a write, you end up with half a file. You can solve that by the atomic writing trick—write a temporary file, then replace the old file with the temporary—but this is hard to get right on Windows (especially with Python 2.x) (see Getting atomic writes right), and again, a database will usually do it for you.
The "right" way to do this is to create a new window class with a msgproc that dispatches to your handler on WM_QUERYENDSESSION. Just as MFC makes this easier than raw Win32 API code, win32ui (which wraps MFC) makes this easier than win32api/win32gui (which wraps raw Win32 API). And you can find lots of samples for that (e.g., a quick search for "pywin32 msgproc example" turned up examples like this, and searches for "python win32ui" and similar terms worked just as well).
However, in this case, you don't have a window that you want to act like a normal window, so it may be easier to go right to the low level and write a quick&dirty message loop. Unfortunately, that's a lot harder to find sample code for—you basically have to search the native APIs for C sample code (like Creating a Message Loop at MSDN), then figure out how to translate that to Python with the pywin32 documentation. Less than ideal, especially if you don't know C, but not that hard. Here's an example to get you started:
def msgloop():
while True:
msg = win32gui.GetMessage(None, 0, 0)
if msg and msg.message == win32con.WM_QUERYENDSESSION:
handle_shutdown()
win32api.TranslateMessage(msg)
win32api.DispatchMessage(msg)
if msg and msg.message == win32con.WM_QUIT:
return msg.wparam
worker = threading.Thread(real_program)
worker.start()
exitcode = msgloop()
worker.join()
sys.exit(exitcode)
I haven't shown the "how to create a minimal hidden window" part, or how to signal the worker to stop with, e.g., a threading.Condition, because there are a lot more (and easier-to-find) good samples for those parts; this is the tricky part to find.
you can detect windows shutdown/log off with win32api.setConsoleCtrlHandler
there is a good example How To Catch “Kill” Events with Python

Python help - Need the ability to restart the script when it hangs or automatically set a timer

I currently have a python script that does exactly what I need it to do, however every now and then the script will hang and the only way to restart it is by killing the script and relaunching it.
I was wondering if there was a way to put in a few commands that will restart it lets say everytime it hangs or when a specific message appears or even just restart it on a timer eg:every 50 seconds.
I cannot provide the code through here, but I can provide it if we talk in private.
I am willing to pay you a bit of money if your fix does work.
please email me at stackoverflow1#shaw.ca
Thanks!
Edit: I see, ok - then is it possible to provide me with some codes which it will restart on a specific timer?
Edit2: Ok thanks everyone for their comments - I will get in touch with the person who built it to see if they can rewrite it from scratch to include a timer.
Cheers.
Feel free to pay me if you want, although it is by no means necessary.
Here:
import time
import threading
import os
def restart():
time.sleep(50)
os.execv('/full/path/to/this/script', ['second argument', 'third argument'])
def main():
t = threading.Thread(target=restart, args=(), name='reset')
t.start()
# ... The rest of your code.
If you have any buffers open that you care about (such as stdout) you'll want to flush them right before the call to execv up there.
I haven't tested this code, because I don't have a python interpreter handy at the moment, but I'd be surprised if it didn't work. That call to execv replaces the current context, so you don't get an increasingly deep hierarchy of child processes. All I'm doing, in case you're curious and want to know what magic phrase to google, is setting a "timer interrupt handler". For the pedants, no, I recognize this thing isn't directly handling any interrupts.
The numeric argument to sleep is in seconds. I would simply request that you not use my code in malware, unless it is for research purposes. I'm particular that way.
edit: Additionally, a lot of it was taken from here.

Is there a cross platform method of dealing with Sleep mode in Python?

I have a Python application that regularly dies when the computer goes to sleep. It works well on Mac, Windows and Linux on it's own, but the sleep problem is irritating.
Is there a function/library that would let me deal with sleep mode in a platform independant way?
Something like
if(OSSLEEP){
#Reduced Functionality
}
I would be happy if the program simply didn't crash, as I realize it is probable that no functionality is possible during sleep.
I researched the question:
How can I check to see if system is in standby mode?
It seems there is a Win32 API function which does this: By this reasoning there might be a Python library that does the same thing.
Notification when Windows enters in sleep mode
This seems to say it's not possible and a bad idea:
Multithreaded python urllib2-based downloader drives the computer to Standby/Sleep
I would love to know if this is do-able even if it's not advisable.
During sleep mode, no program is running. That's kind of the point, since modern CPUs use significantly virtually no power when not doing anything.
Additionally, your problem is not exclusive to the sleep mode. It will also occur if the connection drops out, or if your process doesn't get notified during hibernation, or if your network interface is restarted, or … .
So the correct way to solve your problem is: Ask a new question with your code and the error you're getting.

Capturing stdout from an imported module in wxpython and sending it to a textctrl, without blocking the GUI

There are alot of very similar questions to this but I can't find one that applies specifically to what I'm trying to do.
I have a simulation (written in SimPy) that I'm writing a GUI for, the main output of the simulation is text - to the console from 'print' statements. Now, I thought the simplest way would be to create a seperate module GUI.py, and import my simulation program into it:
import osi_model
I want all the print statements to be captured by the GUI and appear inside a Textctrl, which there's countless examples of on here, along these lines:
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
<general frame initialisation stuff..>
redir=RedirectText(self.txtCtrl_1)
sys.stdout=redir
class RedirectText:
def __init__(self,aWxTextCtrl):
self.out=aWxTextCtrl
def write(self,string):
self.out.WriteText(string)
I am also starting my simulation from a 'Go' button:
def go_btn_click(self, event):
print 'GO'
self.RT = threading.Thread(target=osi_model.RunThis())
self.RT.start()
This all works fine, and the output from the simulation module is captured by the TextCtrl, except the GUI locks up and becomes unresponsive - I still need it to be accessible (at the very minimum to have a 'Stop' button). I'm not sure if this is a botched attempt at creating a new thread that I've done here, but I assume a new thread will be needed at some stage in this process.
People suggest using wx.CallAfter, but I'm not sure how to go about this considering the imported module doesn't know about wx, and also I can't realistically go through the entire simulation architecture and change all the print statements to wx.CallAfter, and any attempt to capture the shell from inside the imported simulation program leads to the program crashing.
Does anybody have any ideas about how I can best achieve this? So all I really need is for all console text to be captured by a TextCtrl while the GUI remains responsive, and all text is solely coming from an imported module.
(Also, secondary question regarding a Stop button - is it bad form to just kill the simulation thread?).
Thanks,
Duncan
I would suggest looking into this WX wiki article about long running tasks.
It specifically addresses the situation you're dealing with using a "start" button to being a long running process. Several different examples are given using different techniques like threads and idle handlers.
I think you would have to redirect stdout to a log file (or simple SQLite database?) and then use your thread to check the log file for updates which it would then pass along to the GUI using wx.CallAfter or similar. You might be able to use something like a socket server built in Python: http://wiki.wxpython.org/AsynchronousSockets. I think the wxPython Cookbook mentioned something about using an RPC server too (probably this one: http://docs.python.org/library/simplexmlrpcserver.html), but I don't remember the details.
You should also try asking on the official wxPython mailing list. They're very friendly over there.

Categories