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.
Related
I have been trying to create a CanvasImage item in python using goocanvas however when I try to use the CanvasImage function it gives me an error.
pb = GdkPixbuf.Pixbuf.new_from_file_at_scale("image2.jpg", 1920, 1080, True)
image = GooCanvas.CanvasImage(pb, 200, 200)
TypeError: GObject.init() takes exactly 0 arguments (3 given)
Am I missing something or am I using a wrong function to create an image on the canvas.
I am referring to this as there is no proper documentation for goocanvas bindings in python: https://developer.gnome.org/goocanvas/stable/GooCanvasImage.html
If Goocanvas is not suitable for python, please suggest a different canvas that I could integrate and use in python.
Thank You
Perhaps it's the call.
This is from the goocanvas github : https://github.com/GNOME/goocanvas/blob/33694b33cc337be86d8c848825a463e52bb1a2c0/bindings/python/demo.py#L190
Also the project's github states that it is no longer supported.
An actively developed and better documented library is PyGObject.
https://pygobject.readthedocs.io/en/latest/index.html
To display images: https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Image.html#Gtk.Image
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.
I am confused by PyQt4. I have tried the following steps on python2.6:
In [1]: from PyQt4 import QtGui
In [2]: import sys
In [3]: app = QtGui.QApplication(sys.argv)
In [4]: pix = QtGui.QPixmap("P1010001.JPG")
In [5]: pix.width(), pix.height()
Out[5]: (0, 0)
Why does width and height show zero? The image exists and is fine. This is completely counterintuitive, which I do not expect from python.
PyQt adds a little syntactic sugar here and there to make things more Pythonic. But it is mostly a fairly thin wrapper around Qt (which is a C++ library) - and so it would be a mistake to expect PyQt to always behave in a way that is intuitive to Python programmers.
I suppose most Python programmers might expect QPixmap to raise an error when setting a path that doesn't exist. But Qt doesn't do this, and, in this case, neither does PyQt. Instead, you can check that you have a valid pixmap by using:
pix.isNull()
To actually fix the code in your example, you will obviously have to change to the appropriate directory first (or use an absolute path).
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.
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