How do I include an image in a window with pygtk? - python

I'm trying to make a program in python which creates a fullscreen window and includes an image, but I don't really know how to do that. I've tried to read documentations on pygtk and I've searched in both goodle and stackoverflow, without any success.
Here's my current code.
def __init__(self):
pixbuf = gtk.gdk.pixbuf_new_from_file("test.png")
image = gtk.Image()
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.fullscreen()
self.window.show()
image.set_from_pixbuf(pixbuf)
image.show()
Question: how do I include an image in a window?

Please provide a little more context (e.g. class definition, imports).
Do not forget to add the image object to your window (before showing image and window):
self.window.add(image)
The tutorial example adds the image to a button, but you can try adding it directly to the main window:
# an image widget to contain the pixmap
image = gtk.Image()
image.set_from_pixmap(pixmap, mask)
image.show()
# a button to contain the image widget
button = gtk.Button()
button.add(image)
window.add(button)
button.show()
button.connect("clicked", self.button_clicked)

Related

How To Set The Window Icon PySDL2

I want to set the window icon in PySDL2. I tried doing this
self.icon = sdl2.ext.load_image("./assets/icon.png")
sdl2.SDL_SetWindowIcon(self.window, self.icon)
But since I'm using sdl2.ext.Window it doesn't work.
Any ideas on how I can go about doing this?
There might be a limit to the quality of the image you place as an Icon.
window being sdl2.ext.Window
image = sdl2.ext.image.load_img(path_to_image)
sdl2.SDL_SetWindowIcon(
window.window,
image,
)
This code was taken from rubato a pysdl2 wrapper Game Engine for python.
Check it out here: https://rubato.app/.
Edit due to comments:
For your code it would look something like this:
self.icon = sdl2.ext.load_image("./assets/icon.png")
sdl2.SDL_SetWindowIcon(self.window.window, self.icon)
You only needed the actual object, stored at self.window.window.
self.window is a pointer?
Instead of using sdl2.ext, I just imported sdl2 and sdl2.sdlimage.
Here is the code if anyone is wondering:
self.icon = "./icon.png"
image = sdl2.sdlimage.IMG_Load(self.icon.encode())
sdl2.SDL_SetWindowIcon(self.window, image)
sdl2.SDL_FreeSurface(image)

Why does Tkinter Canvas widget show images at a wrong scale?

I'm trying to open image files and display them in python 3.8 using Tkinter and Pillow, but something is scaling the images wrong on my screen.
import tkinter as tk
from PIL import Image, ImageTk
class ViewingWindow(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.image = None
self.canvas = tk.Canvas(self, width=500, height=500)
self.canvas.pack()
def setImage(self, img):
self.image = img
print(img.width())
print(img.height())
print(self.canvas["width"])
print(self.canvas["height"])
self.canvas.create_image(0, 0, anchor=tk.NW, image=img)
window = tk.Tk()
canvas = ViewingWindow(window)
canvas.pack()
img = Image.open("500x500.jpg")
img = ImageTk.PhotoImage(img)
canvas.setImage(img)
window.mainloop()
This is the result, shown for reference is Windows image viewer at "show actual size", and Gimp at scaling=100%:
The 4 print statements all show "500", every part of the system seems to agree that the image is shown at 500x500, except the actual pixels on the screen. For whatever reason it's scaled to something close to 750x750, what in the world is scaling my image? This is consistent for all images I've tried to open in Tkinter, and regardless on window size and widget sizes.
Tested on Windows 10 with screen resolution 1920x1080.
it's scaled to something close to 750x750
750/500 = 150%.It seems that your system zoom ratio is 150%.
To show the right image size.Just like furas said,you need to use DPI awareness.Read the problem in MSDN official doc
About DPI awareness.
To solve the problem,you can set the DPI awareness in your code.(Or you can change the zoom ratio to 100%)
In my PC,the are not the same size without DPI awareness.Now after set the DPI awareness:
Add this in your code:
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(2) # this could only be used when your version of windows >= 8.1

Displaying an image in python via Button and Canvas

I am a begginer in python, tkinter. I have written a code that should normally display an image in a canvas.
What happens is that the main frame (gui) is displayed with the menu bar, then when I click on load image, the gui window shrinks (to 100x100 I guess) but nothing is displayed within.
Could you please explain to me why this is happening so I can understand where the error occurs, and how to correct it?
# -*- coding:utf-8 -*-
# Imports
from tkinter import Tk, Menu, Canvas
from PIL import Image, ImageTk
# Function definitions
def deleteImage(canvas):
canvas.delete("all")
return
def loadImage(canvas, img):
filename = ImageTk.PhotoImage(img)
canvas.image = filename
canvas.create_image(0,0,anchor='nw',image=filename)
return
def quitProgram():
gui.destroy()
# Main window
gui = Tk()
# Inside the main gui window
#Creating an object containing an image
# A canvas with borders that adapt to the image within it
img = Image.open("fleur.jpg")
canvas = Canvas(gui,height=img.size[0],width=img.size[0])
canvas.pack()
# Menu bar
menubar = Menu(gui)
# Adding a cascade to the menu bar:
filemenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="Files", menu=filemenu)
# Adding a load image button to the cascade menu "File"
filemenu.add_command(label="Load an image", command=loadImage)
# Adding a delete image button to the cascade menu "File"
filemenu.add_command(label="Delete image", command=deleteImage)
filemenu.add_separator()
filemenu.add_command(label="Quit", command=quitProgram)
menubar.add_separator()
menubar.add_cascade(label="?")
# Display the menu bar
gui.config(menu=menubar)
gui.mainloop()
EDIT:
The second problem is that I want to create a canvas and the image in the main gui window, and pass them as arguments to the menu buttons (See code above, where img and canvas are created separately from the function loadImage). Seeing as putting parenthesis in the command=loadImage() created a problem on its own.
Another point that rises a question in my head : Regarding the first problem which was solved by keeping a reference to the filename=ImageTk.PhotoImage(img). Wouldn't it normally be pointless to keep a reference inside the function since it's a local variable anyway?
As stated in effbot's PhotoImage page, you have to keep a reference of your image to ensure it's not garbage collected.
You must keep a reference to the image object in your Python program,
either by storing it in a global variable, or by attaching it to
another object.
Note: When a PhotoImage object is garbage-collected by Python (e.g.
when you return from a function which stored an image in a local
variable), the image is cleared even if it’s being displayed by a
Tkinter widget.
To avoid this, the program must keep an extra reference to the image
object. A simple way to do this is to assign the image to a widget
attribute, like this:
Your loadImage() method should look like below.
def loadImage():
img = Image.open("fleur.jpg")
filename = ImageTk.PhotoImage(img)
canvas = Canvas(gui,height=100,width=100)
canvas.image = filename # <--- keep reference of your image
canvas.create_image(0,0,anchor='nw',image=filename)
canvas.pack()

PyQt4 - QWidget save as image

I'm trying to use Python to programmatically save a QWidget in PyQt4 as an image (any format would be fine - PNG, PDF, JPEF, GIF...etc)
I thought this would be very straightforward, but I actually wasn't able to find anything on the web about it. Can someone point me in the right direction?
To be clear, I'm trying to do this
gui = <SOME QMainWindow>
gui.show() # this displays the gui. it's useful, but what i need is to save the image
gui.save("image.png") ## How do I do this?
You can do this using the QPixmap.grabWindow() method.
From the docs:
Grabs the contents of the window window and makes a pixmap out of it.
Returns the pixmap.
The arguments (x, y) specify the offset in the window, whereas (w, h)
specify the width and height of the area to be copied.
If w is negative, the function copies everything to the right border
of the window. If h is negative, the function copies everything to the
bottom of the window.
Note that grabWindow() grabs pixels from the screen, not from the
window. If there is another window partially or entirely over the one
you grab, you get pixels from the overlying window, too.
Note also that the mouse cursor is generally not grabbed.
The reason we use a window identifier and not a QWidget is to enable
grabbing of windows that are not part of the application, window
system frames, and so on.
Warning: Grabbing an area outside the screen is not safe in general.
This depends on the underlying window system.
Warning: X11 only: If window is not the same depth as the root window
and another window partially or entirely obscures the one you grab,
you will not get pixels from the overlying window. The contests of the
obscured areas in the pixmap are undefined and uninitialized.
Sample code:
import sys
from PyQt4.QtGui import *
filename = 'Screenshot.jpg'
app = QApplication(sys.argv)
widget = QWidget()
widget.setLayout(QVBoxLayout())
label = QLabel()
widget.layout().addWidget(label)
def take_screenshot():
p = QPixmap.grabWindow(widget.winId())
p.save(filename, 'jpg')
widget.layout().addWidget(QPushButton('take screenshot', clicked=take_screenshot))
widget.show()
app.exec_()
This will produce a window that looks like this:
When you click the button, it will create a file named Screenshot.jpg in the current directory. Said image will look like this (notice the window frame is missing):

Creating Blank Images in Python (allowing pixel by pixel manipulation)

I have this code here that creates a Tkinter Canvas widget, then embeds an image within it.
import Tkinter
from PIL import ImageTk, Image
class image_manip(Tkinter.Tk):
def __init__(self):
Tkinter.Tk.__init__(self)
self.configure(bg='red')
self.ImbImage = Tkinter.Canvas(self, highlightthickness=0, bd=0, bg='blue')
self.ImbImage.pack()
self.i = ImageTk.PhotoImage(Image.open(r'test.png'))
self.ImbImage.create_image(150, 100, image=self.i)
def run():
image_manip().mainloop()
if __name__ == "__main__":
run()
I'd like to be able to create a blank image within the Canvas widget, so that I could do pixel by pixel manipulation within the widget. How would one go about this?
To create a new blank image (rather than opening one), you can use the Image.new(...) method in place of your Image.open(...). It is described in The Image Module.
Then call self.i.put(...) to do pixel-by-pixel manipulation. (i is the PhotoImage object as in your example.)
Here's some general information on The Tkinter PhotoImage Class.

Categories