Background process and tkinter - python

Looking for help on where to start with this, not too good with Python. What I trying to do is use tkinter for a gui interface but i need to be able to process recieved data and update labels widgets as information changes. I all ready have the communication portion of my program working fine in the shell but when I try to tie it to tkinter it will stop processing as soon as the interface is generated. Anyone have a simple code for me to modify to my needs or point me to a reference example somewhere. Spent days so far trying different options and I still have yet to find something that works.
Thanks for any help

Convert your working program into functions that you can register as callbacks in the tkinter UI (say buttons, or other widgets), that is, make it event-driven, and then, for background processing register some of the functions with the after widget method. The root.mainloop() will never return (only on UI close), use it as the last instruction.
So you can't just write your logic in a top-down structure, and hope that it will work well with the UI. The mainloop will be permanently looping, and will call specific funtions in your code, as appropriate to the received events from the user, or to callbacks you registered to run after some time with after.
See here for the after part
Take a look here for structuring tkinter programs. It should have enough info and links for you to study and learn how to do it in a right way.

Related

Python : How to deal with threads priority in Gtk3

I am building an user interface using Python, Gtk3 and Glade. I want to change several things on the UI at the same time (i.e start an animation and display a new text) which leads to the application freezing.
I have read that Gtk wasn't thread safe so I didn't used the Thread module.
Instead, I used Glib.idle_add and Gdk.threads_add_idle functions. I am tryig to update a treeview, display some text and show an animated logo at the same time. The application works but it freezes a few seconds and then everything appears at the same time. I try to set different priorities to the threads but it does'nt seem to fix it.
Gtk.threads_add_idle(Glib.PRIORITY_DEFAULT, label.set_text, "text_to_set")
Gtk.threads_add_igle(GLib.PRIORITY_DEFAULT, function_to_display_logo)
I expect the different texts and the treeview and the logo to be displayed without any freeze. Does anyone know how I can fix that ?
Please have a look here at a script example in https://github.com/f4iteightiz/UWR_scoreboard : a GTK window is updated all 0,2s for example (countdowns of several timers appearing in labels; I think anything else could be updated) and it stay reactiv the whole time. No freezing noticeable.
I found out what my error was. I was using the GLib.idle_add function too many times even in some cases where I had no use for it.
For example in the main code I had :
Glib.idle_add(my_function,buffer)
but my_function looked like this :
def myfuntion(buffer):
GLib.idle_add(buffer.set_text,"text")
I deleted the GLib.idle_add call in the main code and now it works perfectly.

How do I get a value asynchronously while not blocking the UI in PyGTK

good people of the internet.
I'm writing a GUI application that needs to get the ID from an RFID card scanner attached to a Raspberry Pi. I'm using PyGTK in combination with Glade for the UI.
When the user clicks on the 'confirm' button, I want the app to scan for any cards (I have a function with a while True loop for this), but the user should also be able to press the 'cancel' and stop scanning for cards and reset some values.
I wanted to do this by starting the scanning function in another thread (or process) and, once scanned, make that process trigger a callback function to process the ID and run some other code, but I can't find any libraries that allow me to do this the way I imagined it could.
I've tried using Pool but calling pool.apply_async(RFID.Get, callback = self.OnScan).get(timeout=15) still blocks the IO.
I've done some async work in C# before this but am not at all completely familiar with how it's implemented in Python.
(The GUI I'm using.)
I need to get this done A.S.A.P., so any help, hints or clues are appreciated. If I need to supply any code I will (although this project is not open-sourced, so I can't share everything).
Thank all of you in advance.

Inactivate pyside-generated windows for the duration of background task

I have a simple gui application written in python with pyside. There is a main window and also some modal QDialogs. Depending on the user's actions in some of these dialogs, the application might have to connect to a database and perform corresponding tasks in it.
The problem is: database actions might take a few seconds to complete and my users tend to think that the program is stuck, so they start furiously clicking around and mashing keys. To prevent this erratic behavior I want to deactivate all the windows and display some loading symbol to calm things down.
What I need to create (left - normal state, right - busy state):
This is not the actual app, just an approximate schema of what I want to achieve.
I think some kind of QMovie should do the trick, but I have no idea how to cover a dialog with semi-transparent white and to display the loading symbol on top of it. I am also considering QProgressBar, but I am not sure if it's the right solution for the task.
I would appreciate any advice or a link to similar tasks solved (for some reason I was unable to google anything relevant myself, maybe I am using wrong keywords).
Generally, the way you would do this is with some sort of progress indicator, either a QProgressBar or a QProgressDialog.
With the QProgressDialog, you can launch it modally to prevent users from interacting with the base QDialog or QMainWindow.
Either way, you should still be doing the slow-running task in another thread; otherwise, the GUI is just going to freeze. The user won't be able to move the window or dialog, it won't respond to their clicks, and any progress updates you're making won't be shown in the GUI.

Force update GUI in kivy

I am writing an app in kivy which does cpu-heavy calculations at launch. I want the app to display what it's doing at the moment along with the progress, however, since the main loop is not reached yet, it just displays empty white screen until it finishes working. Can I force kivy to update the interface?
Basically I'm looking for kivy's equivalent of Tkinter's root.update()
I could create a workaround by defining a series of functions with each calling the next one through Clock.schedule_once(nextFunction, 1), but that would be very sloppy.
Thanks in advance.
Leaving aside the question of whether you should be using threading or something instead (which possibly you should), the answer is just that you should move your cpu calculations to somewhere else. Display something simple initially (i.e. returning a simple widget from your build method), then do the calculations after that, such as by clock scheduling them.
Your calculations will still block the gui in this case. You can work around this by doing them in a thread or by manually breaking them up into small pieces that can be sequentially scheduled.
It might be possible to update the gui by manually calling something like Clock.tick(), but I'm not sure if this will work right, and even if so it won't be able to display graphics before they have been initialised.

Daemonize, making program to work in background in python/wx.python

I created an complete logger-type program, that logs the certain data from the internet sources. It's GUI I coded in wx.python, now I want to daemonize it (if it is the right term). The program needs to run in background and user has to have option to call/open GUI when he pleases. How can I achieve this with wx.python?
I wouldn't really "daemonize" it per se. Instead, I would just put it in the system tray...at least, that's what I would do on Windows. I assume you can do something similar on the other OSes. Basically you want to bind the frame to wx.EVT_ICONIZE and in that method, you hide it. Then when the user double-clicks the taskbar icon, you want to show it and probably Raise it too.
There's some badly formatted code here: http://bytes.com/topic/python/answers/699757-wxpython-how-minimize-taskbar (I've used a variation of it myself, so I know it works).
And here's some information on Task bar icons: http://www.blog.pythonlibrary.org/2011/12/13/wxpython-101-creating-taskbar-icons/

Categories

Resources