catalina: emacs, python and keyboard input (using psychopy) - python-3.x

i'm facing the following problem.
I use python with emacs on a mac with Catalina OS.
I try to get input from the keyboard in my python script (trhough psychopy library). It does not work, and i receive the following message:
HIDBuildMultiDeviceList: Couldn’t open IOHIDManager.PsychHID-ERROR: Could not enumerate and attach to all HID devices (HIDBuildDeviceList(0,0) failed)!
PsychHID-ERROR: One reason could be that some HID devices are already exclusively claimed by some 3rd party device drivers
I have a similar problem when i try to access the microphone. However, it works from within another editor. It seems that the problem is that i'm denied access to the keyboard (and mic) when running a python script.
Any help would be most welcome.
Best
thibault

I was experiencing the same problem, and restarting solved it!
I had code to play audio files and wait for a key on the keyboard to be hit. This code used to work, and then when I made some changes elsewhere in the code I started for the first time to experience this problem. Using the Python debugger in Terminal (python -m pdb myPsychopyCode.py) I tracked it down to occurring in the 2nd of these lines:
from psychopy.hardware import keyboard
kb = keyboard.Keyboard() # Set up a keyboard device
The error occurred replicably, whether I ran from the whole script or used it interactively in the python debugger. My fix was simply to restart! Thereafter the error messages stopped. I don't like this fix because it means I don't know what caused it or when it might happen again.
2017 MacBook Pro, macOS Big Sur 11.4, external LG monitor, bluetooth external Magic Keyboard, bluetooth external Magic Trackpad.

Related

pyautogui on Container can't Control Mouse

I'm trying to automate mouse and keyboard using pyautogui on linux container on my chromebook (official linux support) however, the mouse and keyboard are not responding to any function (moving, clicking, pressing keys ....) yet something like pyautogui.alert('This is the message to display.') works and pop up a window.
Is there anyway to make it work on the container?
It has been more than a year since this question was asked, and there still doesn't seem to be any answer... I can confirm that this pyautogui problem still exists. One clue, perhaps, is the error message produced if an attempt is made to run under sudo like this:
sudo idle [python program that controls mouse]
This generates the error message:
_tkinter.TclError: couldn't connect to display ":0"
Some folks seemed to suggest that an appropriate EXPORT statement might help this problem, but I couldn't determine the exact details...
I really hope there is some solution/workaround for this problem since manipulating the mouse & keyboard is critical in many applications!

Inconsistent Imagesnap behavior taking pictures on MacOS X, depending on calling environment

EDITED POST
When I first wrote this, I was mystified by the varied behaviors of the "imagesnap" USB cam image capture program on MacOS. Sometimes it took pictures and sometimes it didn't, and this seemed to vary with the environment where it was called: such as directly in a Terminal window, in a shell program, in a Python program running in the Terminal, in a Python program running in the Pycharm IDE, called with os.popen(), subprocess.run(), subprocess.call(), subprocess.popen(), etc.
Sometimes imagesnap would work just fine and take images, and sometimes it would fail silently. I was really having a hard time figuring out why the behaviors were varied, and how to get picture taking using imagesnap on my mac to work reliably when called from a Python program.
I searched on keywords like MacOS, Catalina, imagesnap, USB camera, webcam, Python, PyCharm IDE, shell command, os.popen(), subprocess.run(), subprocess.call(), subprocess.Popen(), and more. I did not find the solution anywhere, and I didn't get an answer here.
I've finally understood the problem better, and that's why I've rewritten this question.
What's behind the inconsistent behavior of imagesnap when called from different environments, and how can I call it from a Linux program and get it to reliably take pictures?
I now understand that MacOS X's privacy settings in System Preferences control which environments are allowed or silently denied to access USB cameras.
For more detail, and a workaround, see my own answer below. I hope that others who understand the issues even more will add improved answers.
ORIGINAL POST:
Below is a simple Python test program. It uses os.popen() and
captures an image from a selected USB webcam using imagesnap -d and
saves an image in image.jpg.
But the imagesnap -d command behaves differently when running in the
PyCharm environment, returning a blank response (' ') and failing to save the requested image.
Submitting this same code WITHIN PyCharm's terminal window fails in
exactly the same way.
But when the same python commands are submitted to the terminal
outside Pycharm, the program takes the image successfully and reports back as shown in the output below.
I'm running Mac OS X Catalina, and using PyCharm 2019.2.3
Community Edition for development. Python version is 3.7.4
Sample code:
import os
return_string = os.popen("imagesnap -d 'DEVICE_NAME' 'image.jpg'").read()
print("'",return_string,"'")
Within the PyCharm development environment this program returns the following and does not create the jpg file:
/Users/mcgregor94086/PycharmProjects/SonaScannerGUI/venv/bin/python
/Users/mcgregor94086/Library/Preferences/PyCharmCE2019.2/scratches/scratch_5.py
' '
Process finished with exit code 0
Outside PyCharm this same code returns:
$ python3
Python 3.7.4 (v3.7.4:e09359112e, Jul 8 2019, 14:54:52)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> return_string = os.popen("imagesnap -d 'DEVICE_NAME' 'image.jpg'").read()
>>> print("'",return_string,"'")
' Capturing image from device "<AVCaptureDALDevice: 0x7fa9bc203330 [DEVICE_NAME][0x141717501bcf0b09]>"... '
>>>
After digging into this problem a great deal, and without any responses, I started to search the web more broadly for answers. And although I found almost no information on the web to guide me what was happening, I now believe that I know what is preventing me from taking pictures programmatically within a python program. I also believe that I now have a reasonable hypothesis as to why I am seeing the results I was seeing.
I have a work around that is currently working, but which I fear may not in the future.
The believe the problem has to do with MacOS and I believe it may vary with the specific release of MacOS. I am currently using MacOS X 10.15.1 Catalina. earlier MacOS X releases might not be as strict.
In the Catalina release at a minimum, ANY connected USB Camera is considered a special device governed by special security, and management of access to the camera device is controlled in the Systems Preferences -> Security & Privacy panel.
When you click the Camera row in the menu on the left of the panel you will see a checkbox list of apps which are allowed to programmatically access you camera. If you unlock the page (lower left), you can change which apps are allowed to access the camera by checking or unchecking them in the list.
On the machines I have available, there is a list of 4 apps in this panel: Terminal, UberConference, Google Chrome, Skype.
The list of available apps varies for other resources, such as Contacts, Calendars, Accessibility, Full Disk Access, etc.
Some of these resources (such as Accessibility and Full Disk Access) selection lists have a pair of "+|-" buttons below the app list that allow you to add, or permanently remove, apps from accessing that resource.
But Camera. Microphone and some other resource do not have such a pair of buttons, and for these devices, the list appear unchangeable by the user.
The panel suggests that the apps get on the list by "requesting access" to the camera, but I have not found an explanation anywhere on line about how to add an app to this access list.
One of the predefined apps in the list is "Terminal". That was checked, so when I ran imagesnap from within a terminal window the program had the necessary privacy privileges and the camera took pictures just fine.
In contrast, when I tried to run a python program within the PyCharm IDE, the PyCharm IDE did not identify itself as a terminal and the request silently failed.
Python has a number of different ways to launch an independent program such as imagesnap. These methods include os.popen(), subprocess.run() and subprocess.Popen(). Some of these methods are deprecated, so we can't rely on them working in the future. Other methods() have additional options which control whether a new "shell" is created or not, and these may complicate determining what environment the app will see.
I found it confusing to try to predict which of these python methods
would succeed in opening the camera and which would not, as well as
their behavior when run inside the IDE vs. in a terminal window.
Perhaps someone else can compile such a table.
Work around: For the present, I was able to work around this problem by using os.popen, by having it open a new terminal with an initial string. This seems to ensure that Apple security sees the parent as the "Terminal" app which we specifically authorized in the control panel.
I then found
os.popen("open -a Terminal.app imagesnap.sh")
worked.
While this work around is working for me at present, I was not happy about using os.popen() instead of one of the subprocess methods, as I worry it may be deprecated. Second, this worked with a shell script ("imagesnap.sh") but I have not figured out how to pass parameters or run executables.
Perhaps a knowledgable reader can help with better suggestions.

Embedded Qt Mouse Pointer Not Showing Up

I've got a bit of an interesting problem here. There are plenty of threads I've found where people are working to hide or get rid of a cursor on an embedded Qt GUI...but I'm trying to get a cursor to show up on an embedded Qt GUI.
I inherited a project that was 'finished' some time ago, and the person who did the most work on the project has moved on. Fast forward to today and there is a need to add a cursor to this functional touchscreen GUI. The system OS is Yocto Linux, and it is running a Qt 5.4 application on a framebuffer.
I've scoured the Qt code and there is nothing there that would hide a cursor. I've added in the appropriate QT_QPA_FB_HIDECURSOR=0 environment variable to my Qt startup script. I've experimented with adding a QCursor obejct to the GUI. Unfortunately none of these things are working. Using the QCusor I am sometimes able to get a cursor up on the screen, but isn't tied to the touch input (the cursor shows up at the position I programatically move it to, but it stays there when I interact with the GUI).
My touch input events are tied into Qt (via QT_QPA_GENERIC_PLUGINS=evdevtouch and QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event9:rotate=180), but for some reason that touch input cannot be tied to a cursor.
At this point I've spent a few days messing around with environment variables and startup script modifications, but nothing I've done has got the result I'm looking for.
Does anybody out there have some ideas on where to look for solutions to this problem?
Thanks!
Ian
So, now 3 months later I think my team and I just came up with a passable solution to this problem.
The path towards the solution started with the Qt Documentation on "Using libinput". The documentation boils down to a few important statements:
Parameters like the device node name can be set in the environment variables QT_QPA_EVDEV_MOUSE_PARAMETERS, QT_QPA_EVDEV_KEYBOARD_PARAMETERS and QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS
The mouse cursor shows up whenever QT_QPA_EGLFS_HIDECURSOR (for eglfs) or QT_QPA_FB_HIDECURSOR (for linuxfb) is not set and Qt's libudev-based device discovery reports that at least one mouse is available. When libudev support is not present, the mouse cursor always show up unless explicitly disabled via the environment variable.
The evdevtablet plugin provides basic support for Wacom and similar, pen-based tablets. It generates QTabletEvent events only. To enable it, pass QT_QPA_GENERIC_PLUGINS=evdevtablet in the environment or, alternatively, pass -plugin evdevtablet argument on the command-line. The plugin can take a device node parameter, for example QT_QPA_GENERIC_PLUGINS=evdevtablet:/dev/event1, in case the Qt's automatic device discovery (based either on libudev or a walkthrough of /dev/input/event*) is not functional or misbehaving.
So, in my system I have the device nodes: event0, event1, event2, event3, event4, event5, mice, and mouse0. Because I'm trying to get the mouse working, I made the assumption that I'd have to use the mouse0 node. This lead to me setting these environment variables:
QT_QPA_GENERIC_PLUGINS=evdevmouse
QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/mouse0
Much to my frustration these environment variables led to nothing. After some time my team and I figured out how to get debug output from Qt source on our system:
Modifying source code in the qtbase directory under our yocto build (roughly /yocto/poky/build/tmp/work/temp build directory/qtbase
Copying qtbase/plugins/generic/libqevdevmouseplugin.so to my hardware (roughly /usr/lib/qt5/plugins/generic)
Running Qt from the command line
We quickly discovered that the input events coming from mouse0 and mice were basically garbage data. On our system we did set up EVDEV in the kernel, so the mouse input was also tied to the device node event0. When we tried setting the Qt mouse parameter to event0 we started to see debug output that looked like real data.
QT_QPA_GENERIC_PLUGINS=evdevmouse
QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/event0
However, the problem of no-mouse-pointer still remained. After a while we looked back at the Qt Documentation, specifically at the 2nd paragraph listed above. As a last ditch attempt we tried adding in the QT_QPA_FB_HIDECURSOR environment variable...
QT_QPA_GENERIC_PLUGINS=evdevmouse
QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/event0
QT_QPA_FB_HIDECURSOR=0
And...voila! After countless hours of debugging and reading documentation, we finally got a mouse pointer.
I think the main crux of our issue was misinterpreting the Qt Documentation.
The mouse cursor shows up whenever ... QT_QPA_FB_HIDECURSOR (for linuxfb) is not set
By "not set", Qt means explicitly defined as FALSE...not simply "not set" at all.
This solution will work for us, but it does leave at least one thing to be desired. Along the way I stumbled across this thread answer on the Unix StackEx which points to the Kernel documentation of input/input.txt. In section "3.2.2 mousedev" you can see the line:
Each 'mouse' device is assigned to a single mouse or digitizer, except
the last one - 'mice'. This single character device is shared by all
mice and digitizers, and even if none are connected, the device is
present. This is useful for hotplugging USB mice, so that programs
can open the device even when no mice are present.
What this means for us is that while we can use event0 (which goes away when we unplug the mouse) for our mouse input event handling, we won't be able to support hot plugging without making some kernel/Qt-source modifications or figuring out how to get mice working as a Qt mouse input parameter.
So, the question of "why does event0 work and not mouse0/mice" still stands...but for now we've got a solution we can live with.
UPDATE: Now a little bit later we've figured out that udev was not working properly on our system. We added udev to the RDEPENDS in our package group for the Yocto build, and now we can set
QT_QPA_GENERIC_PLUGINS=evdevmouse
and we get a working mouse pointer with hotplug support.
I dont know if this applies to your problem (i dont use QT), but there is a
HAVE_TOUCHSCREEN=1 variable in the machconfig file. It is located normally in your BSP-layer in a recipes-bsp/formfactor/formfactor directory.
Setting this to 1 makes the cursor invisible.
Try setting it to 0

How can I create a button (or hotkey) that will automatically connect my bluetooth headset?

I have a bluetooth headset that I would like to be able to quickly switch between connection from my laptop(running windows 8) to my phone. I downloaded autohotkey to help me make a hotkey that would connect to my bluetooth headset, but I was only able to make a hotkey that would open the bluetooth control panel for my specific headset, which is not what I was trying to accomplish. What I am trying to accomplish is a hotkey that would immediately connect my headset when typed.
The code I used in autohotkey, to open the bluetooth control panel(by clicking Ctrl+Alt+B) is:
^!b:: run "C:\Program Files\WIDCOMM\Bluetooth Software\BTWUIExt.exe" /deviceAddr=445ef3aa5294
this code won't work for you as the numbers and letters on the end are a uniqe idendifier for my specific headset. You can find your unique id by opening bluetooth in the control panel and right clicking your headset, selecting properties, clicking the bluetooth tab (remove the dots and colons).
This worked to connect the first bluetooth device in the list (Windows 10)
#SingleInstance,force
;https://autohotkey.com/board/topic/83571-autohotkey-connect-to-bluetooth/
^F1::
Run, bthprops.cpl
Sleep, 2000
Send, {tab}{tab}{enter}{tab}{enter}
Sleep, 200
Send,!{Tab}
return
There is very little information to give exact solution. But from given information I can say:
You can automate GUI with AutoHotkey so that script will go to the
place where unique id is located. In fact, AutoHotkey allows any
GUI automation (conventional or non conventional GUI).
If the unique id is there as a text and you can copy it, then it
also can be automated by several ways. If unique id cant be coped
and is as image, then it is slightly complicated and you need to use some OCR
techniques. In that case you need to make screenshot of that region
and use some OCR script getting text out of it. Or with AutoHotkey pass image to OCR software and get text from it.
After you have text, you can manipulate it the way you like. Most powerfull solution
is Regular Expressions which are supported by AutoHotkey.
When unique id is ready to use, you can use it in Run
command this way:
^!b:: run "C:\Program Files\WIDCOMM\Bluetooth Software\BTWUIExt.exe" %MyUnicIDVariable%
Turns out that the code I have works on its own. If I just wait for about 10 seconds after typing out the hotkey, the headphones connect, and the control panel that opened automatically closes. Quite convenient actually as I didn't expect it to connect or to auto-close the window.
Thanks for the effort anyway!
Try to install [Broadcom Bluetooth 4.0 Driver for Windows 8.1 ] LINK=>> 1 !
At least works fine on my HP-EliteBook-8570p with stereo "BlueDio 99B" headset. After switching the headset ON the Windows connect the device automatically, and switch Audio-Stream into new-attached device. Optimal!
PS - Unfortunately it is still the Problem with Windows 8.1 + Skype( MIC-Problem) :( Windows 8 is the first OS, than not support Skype at all! ;)

Keyboard input in Qt

I am working on a Qt application running on embedded Linux. I am pretty new to this Qt business since I have just started it a month back, so understand that I'm not that object-oriented ... :P
I have the Qt applications running on my target running Linux. The Qt documentation http://doc.qt.io/archives/qt-4.7/qt-embedded-pointer.html says that we have to enable touchscreen, USB keyboard, keypad, etc. by exporting certain variables. Namely,
export QWS_MOUSE_PROTO=tslib:/dev/input/event1
export QWS_KEYBOARD="linuxinput:/dev/input/event0 usb:/dev/input/event2"
well, as you can guess, first line sets the mouse device in QT as touchscreen. "tslib" is the touchscreen library, and the "event1" is the node representing the touchscreen. Similarly, second line is for on-board keypad (event0), and USB keyboard (event2).
Now, the touchscreen work very well. But the problem is with either keyboard. If I do not export the second variable, namely QWS_KEYBOARD , then the application runs fine. But if I do export the second variable, the application goes into stopped state (SIGSTOP) as soon as it is launched. This is evident from ps output. I can not make it work with SIGCONT.
I am going to try and reconfigure Qt from source. Any thoughts are welcome.
Can not believe this but setting the QWS_KEYBOARD variable as null solved the problem.
Found it in the Qt developer FAQ http://developer.qt.nokia.com/faq/answer/why_doesnt_my_keyboard_work_after_i_have_done_an_export_qws_keyboard_dev_tt
export QWS_KEYBOARD=""
Well, it did not completely solve the problem since I still have to include the native keypad along with the USB keyboard.
Anyway, I am able to move to fields using the arrow/TAB keys. Text input works well. Although CAPS-LOCK and NUM-LOCK do not seem to work. SHIFT works. I am able to terminate the application by Ctrl+Alt+Bkspce. So, for the time being, I am able to input text at least.
Will post if any improvements.

Resources