I feel like this should be pretty simple, but I guess I am missing something.
So I want to set the icon of a window with one of the stock images. I have tried:
windowIcon = gtk.image_new_form_stock(gtk.STOCK_DIALOG_AUTHENTICATION, gtk.ICON_SIZE_MENU)
window.set_icon(windowIcon.get_pixbuf())
Python then complains that:
File "./sample.py", line 44, in init
window.set_icon(windowIcon.get_pixbuf())
ValueError: image should be a GdkPixbuf or empty
I try to convert the gtkImage to a GdkPixbuf because when I didn't python complained that
TypeError: icon should be a GdkPixbuf or None
In the pygtk documentation it says:
If the storage type of the image is not either gtk.IMAGE_EMPTY or gtk.IMAGE_PIXBUF the ValueError exception will be raised.
So I guessing that storage type of the stock image is wrong. The question is how to I get around this?
You can use the .render_icon() method on any GtkWidget to provide a stock item as the icon.
windowicon = window.render_icon(gtk.STOCK_DIALOG_AUTHENTICATION, gtk.ICON_SIZE_MENU)
window.set_icon(windowicon)
The render_icon() method works as given above. Your code was having problems, because the get_pixbuf() method was returning None. This is because the image was not created from a pixbuf, and for some reason, it won't convert it. Another way of getting a pixbuf from an image is to use the gtk.gdk.pixbuf_new_from_image() function.
Related
I am following a tutorial on pygame. here is the link->tutorial
On trying the code from tutorial I am getting this error:
NameError: name 'create_graphics_screen' is not defined
But in the link(tutorial) this is the line of code is given. Am I doing something wrong?
import pygame
import sys
background = ["blue50x50.png","green50x50","pink50*50","red50*50","skin50*50","skyblue50*50"]
screen = create_graphics_screen() # this line generates error.
Does "create_graphics_screen" function actually exist in pygame?
If yes do I need to import something to run it?
No, create_graphics_screen() does not exist; replace it pygame.display.set_mode(WIDTH, HEIGHT).
This function will create a display Surface. The arguments passed in are requests for a display type. The actual created display will be the best possible match supported by the system.
The resolution argument is a pair of numbers representing the width and height. The flags argument is a collection of additional options. The depth argument represents the number of bits to use for color.
I'm using a Gtk3 TreeView that looks like above. The model is a Gtk.TreeStore
Gtk.TreeStore(str, GdkPixbuf.Pixbuf)
For the picture I could add to the model the correctly sized images via:
pixbuf.scale_simple(48,48,GdkPixbuf.InterpType.BILINEAR)
However I'm also using the model elsewhere showing the pixbufs in a different manner and the pixbufs can also be a variety of sizes.
What I would like to do is force the size of the picture displayed at run-time. The question is - how do I do that?
I tried forcing the GtkCellRendererPixbuf to be a fixed size, but this just displays the correct size image - but only the portion of the image corresponding to the fixed-size
pixbuf = Gtk.CellRendererPixbuf()
pixbuf.set_fixed_size(48,48)
I thought of using the set_cell_data_func of the TreeViewColumn:
col = Gtk.TreeViewColumn('', pixbuf, pixbuf=1)
col.set_cell_data_func(pixbuf, self._pixbuf_func, None)
def _pixbuf_func(self, col, cell, tree_model, tree_iter, data):
cell.props.pixbuf = cell.props.pixbuf.scale_simple(48,48,GdkPixbuf.InterpType.BILINEAR)
This does do the dynamic resizing of the image at runtime - BUT in the terminal I get hundreds of errors such as this:
sys:1: RuntimeWarning: Expecting to marshal a borrowed reference for <Pixbuf object at 0x80acbe0 (GdkPixbuf at 0x87926d0)>, but nothing in Python is holding a reference to this object. See: https://bugzilla.gnome.org/show_bug.cgi?id=687522
I also tried the alternative by resizing treemodel pixbuf instead of the cell.props.pixbuf but this also gives the same error as above.
cell.props.pixbuf = tree_model.get_value(tree_iter,1).scale_simple(48,48,GdkPixbuf.InterpType.BILINEAR)
So obviously this is not the correct way of doing this - so any thoughts how else to approach this? Any links to example code Gtk3 based C++/Python would be most welcome.
I'm using Gtk+3.6 / python 2.7
Old question, but sadly still relevant - this bug in Gtk still exists. Fortunately there's a pretty easy workaround. All you need to do is to keep a reference to the scaled pixbuf.
I've altered the _pixbuf_func function so that it accepts a dictionary in which it stores the small pixbufs. This gets rid of the annoying warning message and also prevents the pixbuf from being downscaled every single time _pixbuf_func is called.
def pixbuf_func(col, cell, tree_model, tree_iter, data):
pixbuf= tree_model[tree_iter][1] # get the original pixbuf from the TreeStore. [1] is
# the index of the pixbuf in the TreeStore.
try:
new_pixbuf= data[pixbuf] # if a downscaled pixbuf already exists, use it
except KeyError:
new_pixbuf= pixbuf.scale_simple(48,48,GdkPixbuf.InterpType.BILINEAR)
data[pixbuf]= new_pixbuf # keep a reference to this pixbuf to prevent Gtk warning
# messages
cell.set_property('pixbuf', new_pixbuf)
renderer = Gtk.CellRendererPixbuf()
col = Gtk.TreeViewColumn('', renderer)
col.set_cell_data_func(renderer, pixbuf_func, {}) # pass a dict to keep references in
A problem with this solution is that you have to remove the stored Pixbufs from the dict whenever the contents of your TreeStore change, otherwise they'll stick around forever and your program will consume more memory than necessary.
First of all, it is important to mention that I'm learning Python and Gtk+ 3, so I'm not an advanced programmer in these languages.
I'm trying to make a graphical interface in Gtk3 for a Python script that creates a png image, and I'd like to display it, but the PyGobject documentation is so scarce that I haven't found a way to do that. So far, my interface looks like this:
The buttons and text entries are arranged in a grid, and I'd like to keep empty the big space (represented by the big button) to the right until the script finishes building the image, and then show it in that area. The code is here.
Is there a way to do that using Python in Gtk3?
Thanks in advance,
Germán.
EDIT
Taking a look at the demos pointed out by #gpoo I discovered the Frame widget, and I implemented it in my GUI. This is how it looks like:
Inside the window class, I add the Frame to the grid:
self.frame_rgb = Gtk.Frame(label='RGB image')
self.frame_rgb.set_label_align(0.5, 0.5)
self.frame_rgb.set_shadow_type(Gtk.ShadowType.IN)
self.grid.attach_next_to(self.frame_rgb, self.label_img_name,
Gtk.PositionType.RIGHT, 3, 8)
I also connect the Run button to a callback function, so that when I click on it, my script creates and then displays the png image:
self.button_run = Gtk.Button(stock=Gtk.STOCK_EXECUTE)
self.button_run.connect('clicked', self.on_button_run_clicked)
self.grid.attach_next_to(self.button_run, self.entry_b_img,
Gtk.PositionType.BOTTOM, 1, 1)
Finally, my callback function is (no calculations yet, only render the image to the Frame for testing purposes):
def on_button_run_clicked(self, widget):
self.img = Gtk.Image.new_from_file('astro-tux.png')
self.frame_rgb.add(self.img)
but I got the following error when I click the Run button:
(makeRGB.py:2613): Gtk-WARNING **: Attempting to add a widget with
type GtkImage to a GtkFrame, but as a GtkBin subclass a GtkFrame can
only contain one widget at a time; it already contains a widget of
type GtkImage
Any help is appreciated!
You can use Gtk.Image. If you generate a file, you could use:
img = Gtk.Image.new_from_file('/path/to/my_file.png')
and add img to the container (GtkGrid in your case). Or, if you already have the Gtk.Image there, you can use:
img.set_from_file('/path/to/my_file.png')
Instead of ...from_file you can use from_pixbuf, and you can create a Gdk.Pixbuf from a stream.
In general, you can use the documentation for C and change the idiom to Python. Also, you can check the demos available in PyGObject, in particular, the demo for handling images.
Whenever i try and run my pygame program in which I'm trying to load some images I always get plain "pygame.error" and nothing else.
I have imported pygame aswell as pygame.locals. At first i thought that it was because it couldnt find my files but whenever I change the name of a file to something thats incorrect it says "couldnt open image" so i guess that it really does find the file but fails when trying to load it. the startup() function is the first thing that is run from main. and i've also tried to do a simple grass=pygame.image.load('grass.png') with the grass.png file in the same directory as the python file
thankful for all the help i can get
..... line 41, in startup
surroundingsdict = {'gräs': pygame.image.load(os.path.join('images', 'grass.png')).convert_alpha(),
pygame.error
def startup():
pygame.init()
p1=Player.Player(int(random.random()*mapstorlek),int(random.random()*mapstorlek))
vh=ViewHandler.ViewHandler()
surroundingssdict = {'grass': pygame.image.load(os.path.join('images','grass.png')).convert(),
'mount': pygame.image.load(os.path.join('images', 'mount.png').convert)()}
playerdict={'p1': pygame.image.load(os.path.join('images','player.png')).convert()}
pygame.error is usually accompanied by a message with more details about what went wrong, like the 'couldn't open image' you get when you try a non-existant image. Are you sure you get no more info? Can't be sure what's wrong, but I'll throw out two suggestions:
Do you call pygame.display.set_mode to set a display surface before loading the images? You might be doing that in your ViewHandler class, but if not the convert() will fail since it changes the pixel format of the surface to match the display, which it of course can't do if there is no display active.
Another possibility is that you don't have full image support in pygame and can't load .png. Have you tried loading other formats? Try calling pygame.image.get_extended() to see if your pygame is built with extended image support. Even if it returns True there is no guarantee that you can load .png, but at least it's more likely to be something else.
I'm missing something at a very basic level when it comes to loading an image using PIL and displaying it in a window created by Tkinter. The simplest form of what I'm trying to do is:
import Tkinter as TK
from PIL import Image, ImageTk
im = Image.open("C:\\tinycat.jpg")
tkIm = ImageTk.PhotoImage(im)
tkIm.pack()
TK.mainloop()
When I try to run the code above, I get the following:
RuntimeError: Too early to create image
Exception AttributeError: "PhotoImage instance has no attribute
'_PhotoImage__photo'" in <bound method PhotoImage.__del__ of
<PIL.ImageTk.PhotoImage instance at 0x00C00030>> ignored
I've confirmed the file is present and can be opened in an image editor and also that it can be displayed using im.show(). What am I missing?
Tkinter has to be instantiated before you call ImageTk.PhotoImage():
TK.Tk()
It's very true what Meredith said you need to add that line for sure!
I would like to show you my image formatting and then compare it to yours and see if there any different, my code for a image is
master.image = PhotoImage(file="Banditlogo.gif")
w = Label(master, image=master.image)
w.photo = master
w.pack()
And your code is
im = Image.open("C:\\tinycat.jpg")
tkIm = ImageTk.PhotoImage(im)
tkIm.pack()
We are both using PIL with PhotoImage
I can't help wondering are both ways correct?
At this point in time I don't have enough knowledge to fully answer your PIL question but it is interesting to compare both codes as they are different. I can only suggest doing what I do when it comes to example codes people share with me, and that is "if mine don't work, try the example code and see if that fixes the code" when I find something that works I stick with it.
Would someone with more understanding of Tkinter please explane the workings of, How do I use PIL with Tkinter?
Knowledge is power so please share.