How to make buttons in OpenCV 3.1 using cv2.createButton? - python

I'm trying to add a button to my image processing script to save the high and low HSV values for my binary threshold.
According to the OpenCV 3.0 documentation here, OpenCV evidently has a function which does that.
I am writing the function like this
cv2.createButton('Button',f)
Where Button is the name of the button and f is the callback function (just an empty function)
However I keep on getting:-
AttributeError: 'module' object has no attribute 'createButton'
Apparently the same function works fine with C/C++ but it isn't working with python. Most probably because it isn't there for python (maybe) ?
How do I get around this problem?

The documentation says
Another important application of trackbar is to use it as a button or switch. OpenCV, by default, doesn’t have button functionality. So you can use trackbar to get such functionality (found at Trackbar as the Color Palette).
There is a small example how to use it as button.

cv2.namedWindow("Frame")
cv2.createButton("Back",back,None,cv2.QT_PUSH_BUTTON,1)
def back(*args):
pass
The above code shows how to implement the cv2.createButton() method.
Notes:
"Back" = text displayed on the button
back = function called when the button is pressed
the cv2 window must be created before the button
if your button is not appearing: click inside the frame, press ctrl+p or command+p (for mac) and the button menu should appear

I was searching for the reason why the button was getting attached to the control panel of QT window. I think the following extract from CV2 home page would help
The function createButton attaches a button to the control panel. Each button is added to a buttonbar to the right of the last button. A new buttonbar is created if nothing was attached to the control panel before, or if the last element attached to the control panel was a trackbar or if the QT_NEW_BUTTONBAR flag is added to the type
open cv new qt functions page link

I think it's unposible
cv2.createButton('test', GeekObject, None , cv2.QT_PUSH_BUTTON, 0)
cv2.error: OpenCV(3.4.6) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:579: error: (-213:The function/feature is not implemented) The library is compiled without QT support in function 'cv::createButton'

Related

Can't click radio button with pywinauto using UIA backend

On the pywinauto documentation it says that you can click a radio button using the click method:
I have already had issues using the UIA backend, since it is different to win32. In this case, there seems to be no way to click a radio button.
I tried using a window specification:
spec.window(auto_id='RadioButtonManualbackground').click()
AttributeError: Neither GUI element (wrapper) nor wrapper method 'click' were found (typo?)
It cannot find any method called click. I tried using toggle and check and those didn't work either.
I also tried clicking the radio button using the tree hierarchy:
app.Dialog.Analysis.BackgroundCorrection.ManualBackgroundCorrection.click()
pywinauto.uia_defines.NoPatternInterfaceError
Again, this didn't work with toggle or check.
Is there support for clicking a radio button using UIA backend, and how do I do it?
This might be a bit confusing, but radio button wrapper has .select() method which uses SelectionItemPattern. I've found it in test_radio_button unit test.
Proper implementation should check all possible patterns and choose the working one. So I would consider it as a bug: filed issue #549. Thanks for reporting it!
P.S. You always have method .click_input() as a workaround. It performs the most realistic click with moving the cursor.

How to get coordinates of QToolBar icons in PyQt4 application?

I'd like to know how to set position of QCalendarWidget just below the button of ToolBar.
Currently, when user clicks a icon button inside red box,
then the below Calendar() instance is created and the instance is shown in the middle of screen.
What I want to implement is like the following.
You can refer full source code from here.
Any suggestion or advice will be appreciated.
This functionality is already provided by QDateTimeEdit, so you don't need a separate button for it:
def init_toolbar(self):
...
dtedit = QtGui.QDateTimeEdit()
dtedit.setCalendarPopup(True)
Qt Docs: QDateTimeEdit.setCalendarPopup.
This is usually done with a combination of using QWidget.geometry() or QWidget.rect() to get the size and position of a widget (in this case, the clicked button) and then using the QWidget.mapFromXXX and QWidget.mapToXXX series of functions, to transform those into global coordinates and then into widget coordinates that can be fed to QWidget.move()

OpenCV closing a window with a mouse click on a Raspberry Pi

What I want to do is, I want to have have a user click the close "X" button in an OpenCV window and have the program recognize it, and close that window.
It seems that this is not easy, and after four days of going round in circles and finding out how it can be done on a windows machine I am no closer to finding out how to do it on a Raspberry Pi using Python.
I think I need to get the handle of the OpenCV window ( how? ) and then use that to see if the window is still visible ( what call? ) and if it is not, bring proceedings to a halt ( I can do that bit ).
I have tried cvGetWindowHandle("window_name") but I've downloaded the source and GetWindowHandle doesn't seem to be available from python.
The code to capture the left button mouse click event and close a window is fairly simple:
if event == cv2.EVENT_LBUTTONDOWN:
cv2.destroyWindow("window_name")
There is a tutorial on how to use the button click event here which is where I took that code, it provides a full working example in python.
However you are probably running a unix based system on your Rpi and will therefore want to read This answer as you made need a combination of waitKey(1) in order for it to work.
I maybe have a solution but I'm not 100% sure so you'll have to check it yourself:) I assume the OpenCV uses X11 underneath (if no none of this makes sense). With X11 you can:
1) Find X11 window handle for your OpenCV window as described here
2) Use XSelectInput to hook into its event loop somewhat similar to what was done here. I assume you should useStructureNotifyMask as the mask to get the XDestroyWindowEvent event. Run the X11 event loop and as soon as you get the corresponding event you can call the OpenCV destroyWindow function.
This suggestion is based on assumptions and I can't give any guarantees it will work, but as far as I understand if OpenCV isn't built with some other specific window manager this should work. As far as I understand Raspbian was shipped with X11 up to some point and then it switched to Wayland. In case you have an image with Wayland then this probably will not work (and I'm sorry but my Linux skills do not contain a recipe on how to determine which one is used:D).
UPDATE
Actually after more reading I seem to feel that gtkshould be able to handle whatever is being used underneath (X11/Wayland). So if you install gtk development libraries you should also be able to connect to the windows deletion signal like described here. The only question then remains on how to obtain the window handle.
My personal advice - use Qt or some other GUI friendly framework to render the OpenCV images instead of doing it directly with OpenCV. OpenCV is an imaging framework but IMHO highgui is too unusable for anything serious.
all I want to do is to have a user click the close X in an openCV
window
This is how I did it, in a capture loop (RPi stretch, opencv 4.0):
while True:
# do your video capture
# ...
cv.imshow("video frame",frame)
if cv.getWindowProperty('video frame', 1) < 0:
break
getWindowProperty isn't much documented but what it does is, as its name implies, to return the property of a given window. Two of the flags of interest are WND_PROP_FULLSCREEN (or 0) and WND_PROP_AUTOSIZE (or 1). When the window is closed the function returns -1. Use this to immediately break your loop (or close your window if not in a loop).
References:
https://docs.opencv.org/3.1.0/d7/dfc/group__highgui.html#gaaf9504b8f9cf19024d9d44a14e461656
OpenCV Python: How to detect if a window is closed?
Poll with cv2.getWindowImageRect(windowName). It will return (-1, -1, -1, -1) when the user clicks the window close button.
# check if window was closed or image was resized
xPos, yPos, width, height = cv2.getWindowImageRect(windowName)
if xPos == -1: # if user closed window
pass # do whatever you want here if the user clicked CLOSE
I haven't found this documented anywhere; discovered it by accident while handling window resizing. (Tested with OpenCV 4.1.0.)

Grab the focus from GTK popup menu

In my python GTK project, I have a popup menu which pop-ups while typing in a particular text area. But, when type a letter popup menu get the focus and I can't type anymore in the text area until I click on the text area and grab the focus manually. I want to keep the focus to the text area as I type regularly while popup menu comes. Can anyone give tell me a way to do this. I tried widget.grab_focus() method. But it didn't solve my problem.
Also I want to know how to set the position of the popup menu. It always appears near by mouse pointer. I want it to appear near by my application.
Thanks all.
I ran into the same problem using the C API, the solution was to invoke the following functions, I presume they're approximately similar to the python equivalents:
gdk_pointer_ungrab(GDK_CURRENT_TIME);
gdk_keyboard_ungrab(GDK_CURRENT_TIME);
gtk_grab_remove(menu);

Grab Focus for Frame after Shortcut Pressed in wxPython on GNOME

I'm building an app that uses global shortcut keys (using python-keybinder), but there's a problem. The frame pops up and raises properly but doesn't have focus. I have to click on frame.
After I press my keyboard shortcut my frame appears, but it is not focused. I can see that the frame I was focused on previously (e.g. my Firefox frame) still has focus (i.e., the title bar is still white & bold). Only after I click on my app's frame does Firefox's title bar become grey and dim.
I try to SetFocus and CaptureMouse but neither do anything. FindFocus and GetCapture return None.
This only happens on Ubuntu (GNOME). On Windows, the frame gets focus immediately. Is there a way to force GNOME to give focus to my app/frame?
How are you showing the frmae initially, with frame.Show()? I'm not sure if you're saying the frame itself doesn't have focus (but/or a child of the frame does), or your application doesn't have focus?
Are you calling SetFocus in the Frame that initialises all your widgets? It could be an issue of the focus being given to a child of the frame. Try using wx.CallAfter(self.SetFocus) at the end of your Frame.init method - it should ensure the focus is set after all widget creation is done

Categories

Resources