Changing Screen Resolution of Computer using python - python

I'm creating a python program that is supposed to streamline the process of setting up a computer. I want this python program to change the screen resolution of the computer and scaling of it. I'm not sure what the best approach is however, or how to approach it.
I've tried using an example pywin32 program, but it only outputted an array of resolution sizes

I had a look how to change screen resolution using C++ and then translated it to Python:
import win32api
import win32con
import pywintypes
devmode = pywintypes.DEVMODEType()
devmode.PelsWidth = 1366
devmode.PelsHeight = 768
devmode.Fields = win32con.DM_PELSWIDTH | win32con.DM_PELSHEIGHT
win32api.ChangeDisplaySettings(devmode, 0)
We needed a DEVMODE object to pass to the ChangeDisplaySettings function. The pywintypes module which is also part of pywin32 has a function to create objects of type DEVMODE.
We then set the PelsWidth and PelsHeight fields and also the Fields field to tell the API which field's values we want to use.
To change back to the previous resolution, simply call:
win32api.ChangeDisplaySettings(None, 0)
Thanks for asking the question. I've learned something.

Related

PygObject and INTERP_BILINEAR

I'm working on a little project on a Raspberry Pi, and playing with PygObject for the first time.
I'm trying to scale an image, and every example I find says I need to use a flag named INTERP_BILINEAR, but I can't find that anywhere within PygObject/Gtk. I've grep'ed the code base and can't seem to find any reference to INTERP_BILINEAR. I'm sure I'm missing something really obvious, but I don't know what.
pixbuf = GdkPixbuf.Pixbuf.new_from_file(random.choice(pics))
pixbuf = pixbuf.scale_simple(100, 100, <some_package>.INTERP_BILINEAR)
img = Gtk.image_new_from_pixbuf(pixbuf)
INTERP_BILINEAR is GdkPixbuf.InterpType.BILINEAR. I searched for INTERP_BILINEAR in the results of calling help("GdkPixbuf"). Often, Gtk and related modules use this type of formatting when referencing their objects.

What is the appropriate structure to represent a GLFWwindow handle returned be CreateWindow in ctypes.func.argtypes?

I have a simple program in glfw, which uses glfw.glfwSetCursorPos to put the mouse in a certain spot on the screen. However, it was raising a lot of errors, until I found this thread: ctypes.ArgumentError: Don't know how to convert parameter. Now, it works, but one of its parameters is the returned value from glfw.CreateWindow that you want to center on. But, following the accepted and only answer on that thread, I have no idea what variable in ctypes I should use to represent the window in the argtypes for that function, if there even is a variable for a glfw window. And if there isn't one, is there any other way to fix my original problem?
Thanks!
EDIT
Here is a minimal reproductible example. The moment you move the mouse, you can see that it starts spamming to sys.stderr:
import OpenGL
from OpenGL.GL import *
import glfw
glfw.glfwInit()
def onMouseMove(win2, x, y):
print(x, y)
glfw.glfwSetCursorPos.argtypes = [glfw.GLFWwindow,
ctypes.c_float,
ctypes.c_float]
glfw.glfwSetCursorPos(win, float(50), float(50))
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 3)
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 3)
glfw.glfwWindowHint(glfw.GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE)
glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE, glfw.GLFW_OPENGL_CORE_PROFILE)
win = glfw.glfwCreateWindow()
glfw.glfwMakeContextCurrent(win)
glfw.glfwSetInputMode(win, glfw.GLFW_CURSOR,
glfw.GLFW_CURSOR_DISABLED)
glfw.glfwSetCursorPosCallback(win, onMouseMove)
while not glfw.glfwWindowShouldClose(win):
glfw.glfwPollEvents()
glfw.glfwTerminate()
glfwCreateWindow returns a handle to your window. As far as I know, this handle is not represented by any sort of library out there, even glfw. Thankfully, there is a builtin python function that will allow you to create an argument passable to argtypes, type. As far as I know, this only works with the current context, but it does work:
glfw.glfwSetCursorPos.argtypes = [
type(self.win) # or whatever else your window is named
ctypes.c_float
ctypes.c_float]

NameError: global name 'CV_GUI_NORMAL' is not defined

I'm coding using Python and OpenCV on Ubuntu 14.04. When I click on the right button of the mouse, the associated mouse event cv2.EVENT_RBUTTONDOWN does not work and I rather get context menu ("actions"). Is there a way to disable the context menu popup?
A user gave me a hint and I am sure the solution is somewhere there. He asked me to add CV_GUI_NORMAL as shown on here.
So I run: cv2.namedWindow("Window",CV_GUI_NORMAL) but I got this error:
NameError: global name 'CV_GUI_NORMAL' is not defined
When I try cv2.CV_GUI_NORMAL as on the below user's comment instead, I get this error:
AttributeError: 'module' object has no attribute 'CV_GUI_NORMAL'
Note that similar question was asked here but I do not want to change OpenCV code.
How to fix this ?
.
You can use cv2.WINDOW_GUI_NORMAL as follows:
cv2.namedWindow('desired_name_of_window', flags= cv2.WINDOW_GUI_NORMAL)
Allowed windows values in cv2 are:
WINDOW_AUTOSIZE = 1
WINDOW_FREERATIO = 256
WINDOW_FULLSCREEN = 1
WINDOW_GUI_EXPANDED = 0
WINDOW_GUI_NORMAL = 16
WINDOW_KEEPRATIO = 0
WINDOW_NORMAL = 0
WINDOW_OPENGL = 4096
WND_PROP_ASPECT_RATIO = 2
WND_PROP_AUTOSIZE = 1
WND_PROP_FULLSCREEN = 0
WND_PROP_OPENGL = 3
WND_PROP_VISIBLE = 4
The official documentation says:
Python:
cv.NamedWindow(name, flags=CV_WINDOW_AUTOSIZE) → None
Parameters:
name – Name of the window in the window caption that may be used as a window identifier.
flags –
Flags of the window. The supported flags are:
WINDOW_NORMAL If this is set, the user can resize the window (no constraint).
WINDOW_AUTOSIZE If this is set, the window size is automatically adjusted to fit the displayed image (see imshow() ), and you cannot change the window size manually.
WINDOW_OPENGL If this is set, the window will be created with OpenGL support.
Only some implementations with Qt backend support CV_GUI_NORMAL. It seems you have no choice than to install cv2 with Qt support or use other variables.
In that case you'll be using cv2.CV_WINDOW_NORMAL.
For a starter you could build without Qt support if you do not need it. It seems to do more harm than good in many cases. So it is better set the flag WINDOW_OPENGL: That way you disable the QT support and get the OpenGL one.

Copying image to clipboard in python in linux

Ive tried the gtk method, but it is very slow and doesn't work for a 'large' image (120 kb)
import pygtk
pygtk.require('2.0')
import gtk
import os
def copy_image(f):
assert os.path.exists(f), "file does not exist"
clipboard = gtk.clipboard_get()
img = gtk.Image()
img.set_from_file(f)
clipboard.set_image(img.get_pixbuf())
clipboard.store()
Ive tried xclip and it only does text, so what other options are there? What does ubuntu use ?
One way of getting text from/to the clipboard is using XSel. It's not pretty and requires you to communicate with an external program. But it works and is quite fast.
Not sure if it's the best solution but I know it works :)
[edit]You're right, it seems that xsel does not support images.
In that case, how about a slightly modified GTK version.
def copy_image(f):
assert os.path.exists(f), "file does not exist"
image = gtk.gdk.pixbuf_new_from_file(f)
clipboard = gtk.clipboard_get()
clipboard.set_image(image)
clipboard.store()
Do note that you might have to change the owner if your program exits right away because of how X keeps track of the clipboard.
You might want to use the set_with_data method instead, but that's slightly more work (the image data is only sent when an application requests it, so it needs callback-functions). This has also advantages when you paste in the same application instead of to another application.

How to make python window run as "Always On Top"?

I am running a little program in python that launches a small window that needs to stay on top of all the other windows. I believe this is OS specific, how is it done in GNU-Linux with GNOME?
[Update - Solution for Windows]
Lovely, I think I got it working. I am using Python 2.5.4 with Pygame 1.9.1 in Eclipse on Vista 64-bit. Thus, this is for windows systems. The SetWindowPos function is documented Here. I will refer to this in my explanation.
Imports:
from ctypes import windll
Then I set up a variable that calls the "SetWindowPos" in user32:
SetWindowPos = windll.user32.SetWindowPos
Now, let's say I just made a window:
screen = pygame.display.set_mode((100,100), pygame.NOFRAME)
The next line is the key. This sets the window to be on top of other windows.
SetWindowPos(pygame.display.get_wm_info()['window'], -1, x, y, 0, 0, 0x0001)
Basically, You supply the hWnd(Window Handle) with the window ID returned from a call to display.get_wm_info(). Now the function can edit the window you just initialized.
The -1 is our hWndInsertAfter.
The MSDN site says:
A window can be made a topmost window either by setting the hWndInsertAfter parameter to HWND_TOPMOST and ensuring that the SWP_NOZORDER flag is not set, or by setting a window's position in the Z order so that it is above any existing topmost windows. When a non-topmost window is made topmost, its owned windows are also made topmost. Its owners, however, are not changed.
So, the -1 makes sure the window is above any other existing topmost windows, but this may not work in all cases. Maybe a -2 beats a -1? It currently works for me. :)
The x and y specify the new coordinates for the window being set. I wanted the window to stay at its current position when the SetWindowPos function was called on it. Alas, I couldn't find a way to easily pass the current window (x,y) position into the function. I was able to find a work around, but assume I shouldn't introduce a new topic into this question.
The 0, 0, are supposed to specify the new width and height of the window, in pixels. Well, that functionality is already in your pygame.display.set_mode() function, so I left them at 0. The 0x0001 ignores these parameters.
0x0001 corresponds to SWP_NOSIZE and is my only uFlag. A list of all the available uFlags are on the provided documentation page. Some of their Hex representations are as follows:
SWP_NOSIZE = 0x0001
SWP_NOMOVE = 0x0002
SWP_NOZORDER = 0x0004
SWP_NOREDRAW = 0x0008
SWP_NOACTIVATE = 0x0010
SWP_FRAMECHANGED = 0x0020
SWP_SHOWWINDOW = 0x0040
SWP_HIDEWINDOW = 0x0080
SWP_NOCOPYBITS = 0x0100
SWP_NOOWNERZORDER = 0x0200
SWP_NOSENDCHANGING = 0x0400
That should be it! Hope it works for you!
Credit to John Popplewell at john#johnnypops.demon.co.uk for his help.
The question is more like which windowing toolkit are you using ? PyGTK and similar educated googling gave me this:
gtk.Window.set_keep_above
As mentioned previously it is upto the window manager to respect this setting or not.
Edited to include SDL specific stuff
Pygame uses SDL to do display work and apprently does not play nice with Windowing toolkits. SDL Window can be put on top is discussed here.
I really don't know much Python at all, but Googling "pygtk always on top" gave me this:
http://www.mail-archive.com/pygtk#daa.com.au/msg01370.html
The solution posted there was:
transient.set_transient_for(main_window)
You might also want to search things like "x11 always on top". The underlying concept seems to be that you're giving the window manager a "hint" that it should keep the window above the others. The window manager, however, has free reign and can do whatever it wants.
I've also seen the concept of layers when using window managers like Fluxbox, so maybe there's a way to change the layer on which the window appears.
I was trying to figure out a similar issue and found this solution using the Pmw module
http://www.java2s.com/Code/Python/GUI-Pmw/Showglobalmodaldialog.htm

Categories

Resources