Prevent interruption of wand display method on Raspbian - python

I am using wand library in my raspberry project running raspbian and python 2.7.
I have a code part as below to display picture from an url:
with Image(file=urllib2.urlopen(r.text)) as imageOBJ:
display(imageOBJ)
These lines display the image correctly. However, I want this window to stay open and my process to continue with other things in my script. Because after 30 seconds I want to repeat the same thing and change the image in the window. Right now, my code is not running until I close the display window.
Please note that this is not the case on my mac but only on raspberry pi B+ , wheezy raspbian.
How can I prevent this behaviour without closing the image display window?
Thanks in advance

This behavior is expected as both Windows & OS X call the OS's run command start & open respectively -- see reference. On the Raspberry Pi, and other like systems, the wand library calls MagickDisplayImage directly on Python's MainThread.
To emulate like behavior on the Raspberry Pi use the xdg-open utility, and Python's subprocess and tmpfile modules.
Create a temporary file to hold the image
Write image to temporary file
Call xdg-open to open temporary file in an isolated process.
import subprocess, tempfile
from wand.image import Image
with Image(filename='wizard:') as imageOBJ:
tempOBJ = tempfile.NamedTemporaryFile(suffix='.jpg',
prefix='/tmp/myProject-',
delete=False)
imageOBJ.save(file=tempOBJ)
subprocess.call('xdg-open {}'.format(tempOBJ.name), shell=True)
Of course mileage will vary across OS distro/version/desktop-environment.

Related

Screenshotting the windows desktop when working through WSL

I'm primarily using Windows, where I run WSL2. So from a python script running in the subsystem, I would like to screenshot whatever is on windows monitor, as simple as such:
v1
import mss
import os
os.environ['DISPLAY'] = ':0'
with mss.mss() as sct:
sct.shot()
This gives only gives "Segmentation fault" error and no image. So I tried to setup vcxsrv in Windows and I'm able to open stuff from my subsystem in Windows through the server, however I cant get it the other way around..
I just want access to the windows screen so I can screenshot it. Any help about how to access the monitor through wsl would be greatly appreciated, I can't find much on google..
The problem with your attempted solution is that the WSL/Linux Python's mss, as you've found, isn't able to capture the Windows desktop. Being the Linux version of MSS, it will only be able to communicate with Linux processes and protocols like X. Starting up VcXsrv might get you part of the way there, in that you might be able to capture X output, but you may need to be running the Python app from inside a terminal that is running in a X window.
Regardless, you've said that your goal is to capture the entire Windows desktop, not just the X output in VcXsrv. To do that, you'll need to use a Windows process of some sort.
But don't worry; using WSL's interop, you can still do that from inside WSL/Linux Python. We just need to call out to a Windows .exe of some sort.
There are literally dozens of third-party apps that you could use in Windows to create a screenshot. But I prefer to use a solution that doesn't require any additional installation.
So I resorted to PowerShell for this, since you can easily call powershell.exe and pass in a script from WSL. There are a number of examples here on Stack Overflow, but I ended up going slightly "lower tech" to try to simplify a bit. The code here is most similar to this solution, so refer to that if you want to expand on this.
From WSL/Linux Python:
import os
os.system("""
powershell.exe \"
Add-Type -AssemblyName System.Windows.Forms
[Windows.Forms.Sendkeys]::SendWait('+{Prtsc}')
\$img = [Windows.Forms.Clipboard]::GetImage()
\$img.Save(\\\"\$env:USERPROFILE\\Pictures\\Screenshots\\screenshot.jpg\\\", [Drawing.Imaging.ImageFormat]::Jpeg)\"
""")
That essentially sends the ShiftPrintScreen key chord to capture the current desktop to the clipboard, then saves the clipboard. It can get slightly hairy with the quoting, since you are essentially wrapping PowerShell inside a /bin/sh inside a Python script.
Note that, even though you are in Linux Python, since it's the Windows PowerShell that we are calling, it takes the Windows path format (C:\Users\Username\Pictures...) rather than the Linux version (/mnt/c/Users/...).
While I didn't have any timing issues with this, you may need to insert small delays. Again, refer to the existing answer for that. This solution is primarily to explain how to do it through WSL's Python using PowerShell.
if you are on a laptop you could hit the windows button and prtsc to take a screenshot and if you are on PC you could use OBS its recording software that can do pretty much anything.

Raspberry Pi: Enable or disable touch screen from Python script

I am working with Raspberry Pi 4 B, 8 gb RAM and Raspbian OS. I am having 7" touch screen attached to PI.
In my project, I want to make touch screen sleep if there is no activity detected for 5 mins from the Python script (just to save some power). Is there any shell command I can use in the Python script?
There is the option in config.txt of "disable_touchscreen=1" which will stop the Pi polling the controller board for touch input. It also doesn't start the firmware side of the touchscreen input driver, which should stop the Linux side loading either. The display side will work exactly as before.
This file is normally accessible as /boot/config.txt from raspbian OS.
You can read config.txt and modify using following python code
import ConfigParser
config_parser = ConfigParser.ConfigParser()
config_parser.read('config.txt')

Tkinter program compiled with pyinstaller crash on launch

I'm asking help today because I'm new to Tkinter and Pyinstaller (and python in general) and I'm having troubles with it.
I have a simple app working with sqlite, tkinter and pyinstaller to compile all of this in an executable program, the entrance point of my program is a file named main.py
This file calls all the dependancies (like the sqlite module for python, tkinter and my other files like classes etc...)
I made a very simple interface, with a Hello World in a tkinter label and a button to go to page 2 which displays page2 (also in a label), just to see if I'm capable of making it all run and compile all of these pieces together.
I can run it throught my shell executing it like : python main.py and everything is working fine.
But when I run pyinstaller on my linux machine, and start executing the program, nothing appears, my database.db (sqlite database file) is created but I don't have any interface like when I run it with my shell. The thing is getting even worse on windows where, once I've my .exe it just opens a shell and crash after few seconds, not even creating the database.
What I did is I created a 'log file', in which I write the steps of the program.
As you can see on the following picture, the 2 first prints are wrote in my log file (on linux), so I think it crashes when I try to create the window.
If any of you have an idea on what I do wrong, I would really appreciate help :)
General
From the PyInstaller manual:
Before you attempt to bundle to one file, make sure your app works correctly when bundled to one folder. It is is much easier to diagnose problems in one-folder mode.
As the comments suggested, use a catch-all try/except block to log all exceptions to a file. That is probably the best way to see what is really happening. Make sure that the logfile is created in an existing location where you have the necessary permissions.
I would suggest to take advantage of the built-in logging module instead of creating your own. It can e.g. automatically add from which file a log line was created.
IMHO, it is probable that the failures on Linux and ms-windows have completely different causes. You should probably treat them as different issues.
Linux
When you use single file mode, that file is unpacked into a temporary folder, probably somewhere in /tmp. Some Linux distributions mount the /tmp filesystem with the noexec flag. This is incompatible with PyInstaller.
ms-windows
On windows, there are basically two different Pythons; python.exe and pythonw.exe. Basically it is one of the quirks of windows that this is necessary. The latter is for GUI programs like tkinter programs. A tkinter script should not show a cmd window. So I'm guessing that PyInstaller calls your command with python.exe instead of pythonw.exe. From the manual:
By default the bootloader creates a command-line console (a terminal window in GNU/Linux and Mac OS, a command window in Windows). It gives this window to the Python interpreter for its standard input and output. Your script’s use of print and input() are directed here. Error messages from Python and default logging output also appear in the console window.
An option for Windows and Mac OS is to tell PyInstaller to not provide a console window. The bootloader starts Python with no target for standard output or input. Do this when your script has a graphical interface for user input and can properly report its own diagnostics.
As noted in the CPython tutorial Appendix, for Windows a file extention of .pyw suppresses the console window that normally appears. Likewise, a console window will not be provided when using a myscript.pyw script with PyInstaller.
Also, on windows it can matter which Python distribution you're using. I used to be a fan of Anaconda, but lately I've come to prefer the python.org version because it gives me less headaches. On anaconda Python I had the problem that tkinter programs would not launch without showing a cmd window, whatever I tried. Only switching to python.org Python solved that problem.

Pycharm, OpenCV execute on remote server and display Image locally

I set up PyCharm for remote debugging according to this tutorial on CodeProject
http://www.codeproject.com/Tips/987276/Remote-Programming-of-RaspberryPi-using-PyCharm
I am now wondering if it is possible to execute a Python Script with the help of PyCharm on the RaspberryPI and receive the output in PyCharm. Specifically I want to do some image processing and display the image with the help of OpenCV. It would be great to get the image displayed on my Windows machine, not on the Pi.
Another usecase, I want to create some matplot figure, execute the script on the pi and show the Output back in PyCharm on my Windows machine.
Is this possiple?
Kind Regards
You can do this using OpenCV Image Viewer Plugin. Debug you program using remote interpreter in Pycharm, stop at the breakpoint and choose "View as image".
https://plugins.jetbrains.com/plugin/14371-opencv-image-viewer
Disclaimer: I'm an author of this plugin

How to use cd terminal command in Python

Question
How can I change the active directory on the raspberry pi using cd and the subprocess module?
Background
Since I absolutely hate to use the command line, I am trying to create a basic GUI text-editor which can also compile my programs. For now, I am just trying to change the directory to Desktop. To do this, I am using the subprocess module. Here is my current code:
from subprocess import *
call(["cd","Desktop"])
In the terminal, this line (cd Desktop) would change the active directory to Desktop. Oddly, when I run it through subprocess, I am given this error:
OSError: [Errno 2] No such file or directory
Tech Specs
Raspberry Pi Model B
Raspbian "Wheezy" OS
I would try os.chdir
import os
os.chdir("/path/to/dir")
i don't mean to derail the original question, but if you're trying to automate a lot of tasks, you can use the fabric module.
it has a rather simple syntax like this:
with cd('/path/to/app'):
with prefix('workon myvenv'):
run('./manage.py syncdb')
http://docs.fabfile.org/en/1.6/api/core/context_managers.html
it's designed for remote usage over ssh, but many people use it for a lot of local management & deployment
the lcd command works on your local machine:
with lcd('/path/to/app'):
with prefix('workon myvenv'):
run('./manage.py syncdb')

Categories

Resources