Using a pyqt widget from a linearly running console application - console

My scenario here is the following: I am using a pyqt widget to display a solid color fullscreen on a second display and observe this display with a camera that is continuously capturing images. I do some processing with the images and this is the data I am interested in. This works great when used interactively with ipython and matplotlib using the qt4agg backend like so
% ipython -pylab
# ... import PatternDisplay, starting camera
pd = PatternDisplay(); pd.show(); pd.showColor(r=255,g=255,b=255)
imshow(cam.current_image)
I need a similar behavior now in a console script though: it should display the PatternDisplay widget, capture an image, than change the color on the PatternDisplay and take a new image and so on.
The problem is now that the PatternDisplay is never updated/redrawn in my script, likely because PyQt never gets a chance to run it's event queue. I had no luck trying to move the linear worker part of my script into a QThread because I cannot communicate with the PatternDisplay Widget from another Thread any longer. I tried to replicate the implementation of ipython/matplotlib, but I didn't fully understand it, it is quite complicated - it avoids running the QApplication main loop via monkey patching and somehow moves QT into it's own thread. It then checks periodically using a QTimer if a new command was entered by the user.
Isn't there an easy way to achieve what I want to do? I am gladly providing more information if needed. Thanks for any help!

What you need is easier than IPython's job - IPython makes the Qt application and the command line interactive at the same time.
I think the way to do it in Qt is to use a timer which fires at regular intervals, and connect the signal to the 'slot' representing your function that gets the new image and puts it in the widget. So you're pulling it in from the event loop, rather than trying to push it.
I've not used Qt much, so I can't give specifics, but the more I think about it, the more I think that's the right way to do it.

I solved the same problem (i.e. interactive ipython console in terminal, and GUI thread running independently) in the following way with ipython 0.10 (code here)
1. Construct QApplication object, but don't enter its event loop explicitly
2. Run the embedded IPython instance
3. Run the UI code you need by instantiating your window and calling show() on it (like here with the yade.qt.Controller(), which I aliased to F12. (I did not find a way how to ask the embedded shell to run a command at the start of the session, as if the user had typed it)
(You can also show() your window first, then run the embedded ipython. It will provide event loop for Qt.)
(BTW I also tried running Qt4 from a background thread (using both python threads module, and Qt4.QThreads), but it refuses to run in such way stubbornly. Don't bother going that way.)
The disadvantage is that UI will be blocked while ipython is busy. I hope to finding something better for 0.11, which should have much better threading facilities (I asked on ipython-users about how to unblock the UI).
HTH, v.

Related

gnome-shell-extensions drag and drop

While trying to add D&D support to a gnome-shell-extension that I'm writing I ran into a bit of trouble. I can create drop targets to any open window, but that's all I've managed to pull off.
I can't differentiate between the windows. I tried to use global.get_stage().get_actor_at_pos(Clutter.PickMode.ALL, x, y).get_parent().get_parent().get_meta_window().get_wm_class(), but half the time it gives me the wrong window and every now and again it just returns null. Also I'm not sure how to drop the information into the target.
All I'm trying to do is drop a file URI into a browser window or the file into a file manager.
Is it even possible in gnome-shell-extensions and how would I pull it off? Any advice would be welcome!
Here is the current available shell code about DND between windows: https://github.com/GNOME/gnome-shell/blob/master/js/ui/xdndHandler.js You can do practically nothing with it.
In Mutter, there are more than one procedure to handled a drag and drop in a window, because there are one implementation for X11-windows and another implementation for Wayland-windows.
To be honest, i don't know if there are a way on Wayland and how will be.
I can tell you that in gnome-shell (Mutter to be specific) there are not a fully implementation of this ability on X11. Most you can know, it's if a drag and drop occurs from a window to the shell and the position of the dragged actor, but the shell dosen't provide any api to create an internal drag and drop from the shell to a particular window.
The shell drag and drop that you can fully used, it's only an internal (just the shell) drag and drop from and to the shell (only for clutter actors) and not an external one between different windows.
In X11, the drag and drop process occurs between windows only. One window provide the dragged object and the information that it's associate to that object. The another window (could be the same) will accept the drop of the object, taking on account the information that the first window provide.
As there are not way in the shell to be possible setting the requiered information to the target-window and like your GUI is inside a big top window (The window that represent the shell global stage: https://github.com/GNOME/mutter/blob/6c18bae83cd27a7397a1ed0c1c0c81b282f1b44e/src/compositor/meta-dnd.c#L152) and like you don't have access to this big internal window, finally you can not do anything to interact directly with other windows.
Here (https://github.com/swayfreeda/blender-2.77a/tree/5969d704f44952ea8cbecba2ba4150fb4a48e6de/extern/xdnd) you can find a fully implementation of drag and drop on X11, you will need to modify the code to be adapted to the Mutter workflow and then add this code to Mutter. After that you will have support, but you will need to create the corresponding procedured to then invoked the functionalities, provide information and recive usefull events from the shell to the window, to be possible finally control it in gjs, but it will be only for X11, not for Wayland. I suppose you will need to do something similar if you want support on Wayland.
Good loock.

R tcltk responsive gui during calculation

Hello dear stack overflow community.
i'm currently working on an R project for statistical calculations that involves a gui and also time consuming heuristics. in the gui shall be an button to start and stop the calculation and a textfield that reports the best error so far.
so i'm stuck with the question how to keep the gui responsive during the calculation.
some example code
require("tcltk")
result<-tclVar("")
start<-function(){
active<<-TRUE
tkconfigure(button,text="stop",command=stop)
dostuff()
}
stop<-function(){
active<<-FALSE
tkconfigure(button,text="start",command=start)
}
dostuff<-function(){#this would be the optimization function
while(active){
tclvalue(result)<-#do some stuff
}
}
toplevel<-tktoplevel()
button<-tkbutton(toplevel,text="start",command=start)
entry<-tkentry(toplevel,textvariable=result)
tkpack(button)
tkpack(entry)
in the do stuff function some multithreading stuff seems to be necessary. its a requirement to work on windows and linux. i'm hoping for ideas how to archive this. thanks in advance
I think the easiest way is to start an R script as background process using system or system2 with the wait=FALSE parameter so that the long running calculation is processed in the background.
If you want to update the UI to show intermediate results or progress the R script must write the current state into an "exchange" file that can be used to update the UI.
To update the UI you have to check for the new state periodically e. g. by using the after command of Tcl/Tk, see:
http://www.tcl.tk/man/tcl/TclCmd/after.htm
For an example of starting an R script as background process see here:
http://stackoverflow.com/questions/14208976/r-run-source-in-background
Note that R is single threaded and updating the Tk-UI must be done from the same thread (process) that created the UI since the main event loop is running here.
Also take care that you shouldn't allow the user to make conflicting changes via the UI while the background task is running (e. g. starting another background task - except you want to support this).
Canceling the background process via the UI ("cancel button") can be done best by using another "signal file" that is checked by the background process periodically.

Qt widget stops receiving paintevents

I have been doing an implementation of Conways game of life in PySide [source]. So far it works good until a point in which, under certain conditions I havent figured out yet, the QGraphicsView i use to display the grid (which consists of several QGraphicsRectItems on a QGraphicsScene) suddenly stops being painted continuously. The rest of the window remains responsive and the game thread keeps running and signaling for the ui to update the current generation number. It is only when the window gains focus that the graphicsView updates for about a second and then freezes again.
I find this behavior particularly strange given that i dont override paintEvent, nor call repaint/update methods at all, but what the game thread does is to update every RectItem's brush color according to the status it should have every generation.
Any ideas on what could be causing this?
btw this is on Kubuntu 14.04.3 / KWin 4.11.11 / Qt 4.8.6
Managed to solved it myself! In case someone runs into same issue, all that i needed to do was to schedule an update by calling the update method of the qgraphicsscene every generation (i.e. after operating on the graphicRects from the game thread).
I assume the strange behavior was probably the result of trying to save cpu load, since for the gui thread there was no work to be done!

tcltk block input while processing in r

RGTK2 block user input while processing its explain how to block user input using RGTK2 but I dont know how to add that code to my GUI code, im using tcltk. What I want same like in RGTK2 block user input while processing but using tcltk2
I use this code to run button "filter cluster" and the command function is filter (function to do something)
tkpack(tkbutton(f4, text='Filter Cluster', command=filter), side='left',padx= 5, pady = 20)
In tcltk, you would use tkgrab.set on a non-responsive window and tkfocus on a window that has a binding on the <Key> event that prevents further processing. An inconspicuous tkframe is great for that sort of thing — set it to size 1×1, but ensure it is on the screen — as it has no default behaviour to get in the way. (You'll also want to make a bunch of cosmetic changes, such as marking the widgets as disabled and setting the cursor to watch.) In 8.6, there's tk busy (call with tcl("tk","busy",…) since the Tcl tk command appears to not have a convenient mapping) which makes this all much easier (though I don't know if/how that's mapped into R). The simplest way to release a grabbed window is to destroy it, but you can also tkgrab.release.
Do not use a global grab. They're easy to get wrong and can cause you a lot of grief. (If you insist, you're strongly recommended to make mouse activity cancel it and to test very thoroughly. Locking up your display is not a pleasant experience!) The default local grabs are less of a problem, since you can switch to another program and kill off a stuck app if necessary.
The full documentation for Tk (and Tcl) is online; pick the version of the docs for the version of the library that you're using, probably 8.5, hopefully 8.6 ('cos it has some nice extras) and possibly 8.4 (old skool!) As the R documentation for tcltk says, you can invoke anything in Tcl or Tk through tcl(…), passing in the words of the command name and arguments as many strings… (Tcl is a naturally var-args language and uses that extensively.) The limited scope of the default convenience mapping should not hinder you substantively.
General advice, not so closely related to your question
Most Tk programmers try to write their code to not lock users out that way if possible. You get a better user experience if you can keep the GUI responsive and instead just temporarily disable (via the state option on most reactive widgets) the parts that would otherwise trigger reentrancy problems for the duration. (The long-running processing might be also event-driven, or put in another thread, or even delegated to a sub-process. Just remember, Tk GUIs are strictly single threaded — the implementation assumes this very deeply, though it's possible to have wholly independent apps in different threads, if rather hairy to get working right — so you've got to come back to the GUI thread to update anything in the GUI.)

Debug image processing into Qt loop

I have the following algorithm (working):
Acquire image from webcam
Process image
Send image to GUI and show it
The GUI interface is programmed with Qt, and all image acquirement and processing is been doing with OpenCV. There are 3 classes involved, call them Acquire, Process and Gui.
Acquire (Inherits from QObject) grabs the image and calls to Process (Does not inherit from QObject) to make the image processing. Process returns the result to Acquire, who emits a signal caught by Gui (Inherits from QObject), who converts the image (in Mat format) to QImage and draws it.
I am introducing changes into the Process class and I would like to have a visual feedback. As everything is been executed into the Qt's loop I can not use the cv::namedWindow and cv::imshow functions (nothing appears).
The question is: There is any quick method to make visual debugging to know what is happening inside Process without make Process and Gui friends, or connecting them using the signal/slot mechanism or any other solution that involves big changes into the program structure?
You can create another class and put all code for debug output into it. Connect Process to this class to send debug information.

Resources