Remove border of tkinter button created with an image - python

I've created a couple of buttons using my program and I've made them include images. However, I wish to now remove the border that remains (see http://i.imgur.com/XRlmq39.png for screenshot).
The code for the "back" button as an example:
backbutton = ttk.Button(mainframe, command=homereturn)
backbuttonimage = PhotoImage(file="back.gif")
backbutton.config(image=backbuttonimage)
backbutton.pack()
backbutton.grid(column=0, row=1)
Any help would be greatly appreciated.

backbutton = tk.Button(..., highlightthickness = 0, bd = 0)
This works for Python 3.x, I tried...
icon = PhotoImage(file="lock.png")
self.company_lock_button = Button(self.control_lock_frame, image = icon, highlightthickness = 0, bd = 0)
self.day_lock_button = Button(self.control_lock_frame, image = icon)
self.hour_lock_button = Button(self.control_lock_frame, image = icon)

If you are using images to define a custom button, use the standard button class rather than the ttk button class. This will allow you to set the borderwidth attribute to zero:
import tkinter as tk
...
backbutton = tk.Button(..., borderwidth=0)
(unrelated: there's no point in calling backbutton.pack() and immediately follow it with backbutton.grid(...) - you can only use one for a particular widget, and the last one you call is the one that has any effect. In this case the call to pack is completely useless)

Using a new Mac I had the same issue and none of the other answers fully removed the border surrounding the button. I found that setting highlightbackground to the canvas's background color did the trick.

I had the same issue with imaged buttons. Neither bd=0 nor highlichtthickness=0 alone helped. I even suspected the relief-option to play it's part.
What finally helped (with me): pady=0, padx=0
So for the question asked: backbutton.config(image=backbuttonimage, highlichtthickness=0, pady=0, padx=0) could work.

You can use highlightthickness=0 and bd=0

None of the solutions provided so far worked in my case.
(I can only suspect that this is related to the new MacOS GUI style policy of recent versions (I'm using Big Sur). Also other style options don't work on MacOS, e.g. the relief option doesn't have any effect on the appearance of a button.)
Here is my solution: when you put an image to a button, the options width and height take pixels as unit. When you chose small values, i.e. 10x10, the border seems to be covered by the image. Voilá!

Here's one way you could do it..
Use ttk.Style() to set the button's background color to the color of mainframe.
root_color = "red" #Just an example, can't remember the default tk window color
mainframe = tk.Tk() #or whatever mainframe is
mainframe.configure(bg = root_color)
style = ttk.Style()
style.configure('TButton', background = root_color)
backbutton = ttk.Button(mainframe, command=homereturn)
backbuttonimage=PhotoImage(file="back.gif")
backbutton.config(image=backbuttonimage)
backbutton.pack()
backbutton.grid(column=0, row=1)
As a side note, you don't have to specify style = .. in your ttk button here because you are configuring the default TButton style ttk uses. If you defined a custom style for this button you would have to specify this in the keyword arguements for the button.
An example would be giving your button rounded edges instead of using images to achieve the desired effect.

If you are using the import function as:
from tkinter import *
Button(main_scr, text = "OK", bg = "yellow", bd = 0, command = delete1).pack()
The bd = 0 would not show the border.

Not all themes support changing borderwidth. Try using tkinter.tk instead of using ttk.Button.
Use keyword borderwidth=0 for Button's parameter.
You cannot use both backbutton.pack() and backbutton.grid(). You can select one of them.
Snippet:
from tkinter import ttk
import tkinter as tk
mainframe = tk.Tk()
def homereturn():
print('hello')
backbutton = tk.Button(mainframe, command=homereturn, borderwidth=0)
backbuttonimage = tk.PhotoImage(file="p1.png")
backbutton.config(image=backbuttonimage)
backbutton.pack()
mainframe.mainloop()
Screenshot w/out border:

Related

Tkinter active fill by tag

I'm designing a GUI application using Tkinter and for this project, I need buttons for the menu. While looking into the buttons I wasn't blown away by the customization options that come with the buttons, especially when I found out that you can bind click arguments to rectangles.
This allows me to customize the "button" in (almost) limitless ways, but to allow me to put text on the button I need to create a rectangle element and a text element and bind them together using Tkinter's tag_bind property.
One of the design properties of the button that I wanted was active fill when the user moused over the element. Right now I'm just using activefill="" which works, except the text element and the button element will only fill while the mouse is over that element. So, for example, when I mouse over the button the button excluding the text will highlight and vise versa when I mouse over the text.
Below is a simplified (for brevity) version of what I use to generate the buttons;
button = canvas.create_rectangle(button_width, button_height, 10, 10, fill="000", activefill="111", tags="test")
text = canvas.create_text((button_width/2), (button_height/2), activefill="111", tags="test")
canvas.tag_bind("test", "<Button-1>", "foo")
Is there a way to bind the active fill function to a tag rather than a specific element?
Another option is that I completely missed a bunch of information about customizing the buttons in Tkinter, and I would not be apposed to learning about that.
Option 1
I would personally not go for the presented solution. I do not know if you are using the button provided by tk or ttk. But, with the tkinter.tk, you could absolutely change the appearance of the button.
Following, I give you an example that produces a button with the following characteristics:
Blue foreground
Flat appearance
When hovered, the background is green
When pressed, the background is red
The code is as follows:
import tkinter as tk
root = tk.Tk()
# Function hovering
def on_enter(e):
btn['background'] = 'green'
def on_leave(e):
btn['background'] = 'white'
# Create the button
btn = tk.Button(root, background='white', activebackground='red', foreground='blue',relief='flat',text='Test',width=20)
btn.pack()
# Bindings
btn.bind("<Enter>", on_enter)
btn.bind("<Leave>", on_leave)
# Loop
root.mainloop()
Option 2
If even after having tried the tk.Button, you are not glad with the result, I would create a Frame containing a Label (you can do nearly anything with that combination). Then, you could change the background of the frame according to any user action, like:
import tkinter as tk
root = tk.Tk()
# Function hovering
def on_enter(e):
lab['background'] = 'green'
def on_leave(e):
lab['background'] = 'white'
# Click
def on_click(e):
print("hi")
# Create the frame with a label inside
fr = tk.Frame(root)
lab = tk.Label(fr, text="Test", width=20, background="white")
# Packing
fr.pack()
lab.pack()
# Bindings
fr.bind("<Enter>", on_enter)
fr.bind("<Leave>", on_leave)
lab.bind("<Button-1>", on_click)
# Loop
root.mainloop()
You could even create a class with the above combination.

tkinter fill=Y does not work with Button [duplicate]

I am familiarizing myself with Tkinter, and I am attempting to write a very simple program, which displays a button in a window, using the pack geometry manager.
I was experimenting with various configuration options for pack(), such as expand, fill, and side, and I've run into a peculiar problem. I have written the following code:
from Tkinter import *
root = Tk()
widget = Button(root, text='text')
widget.pack(expand=YES, fill=BOTH)
root.mainloop()
The problem is that the button expands to fill the window in the horizontal direction, but not the vertical direction. This is the same result that I get if instead of specifying fill=BOTH I use fill=X. In addition, if I specify instead fill=Y the button does not expand in either direction. Something seems to be going wrong with the fill in the vertical direction, and I cannot figure out what it might be.
I attempted to Google this problem and surprisingly found no mention of this happening to anyone else. I am using a Mac with OS X Yosemite and running python 2.7.5. I also attempted to compile with python 3.4.1 and saw no change.
Edit:
Based off of the answer and comments below, it is clear that there is nothing wrong with my code, because it seems to work on other machines. If not an error in the code, does anyone know what could possibly be causing the button to not stretch vertically when I run the above code?
This is a feature of native buttons on OSX. Buttons on OSX will be a fixed height and will not expand vertically. There is nothing you can do, short of using a different widget such as a label.
try running this code to see the behavior of fill and expand
from Tkinter import *
root = Tk()
root.geometry("500x500")
widget = Button(root, text='text1')
widget.pack(fill=X, expand=1)
widget = Button(root, text='text2')
widget.pack(fill=Y, expand=1)
widget = Button(root, text='text3')
widget.pack(fill=BOTH, expand=1)
root.mainloop()
Argument fill does fill in vertical direction as well
I am also beginner, defining geometry for fill was missing in your code as given below:
from Tkinter import *
root = Tk()
root.geometry("600x400")
widget = Button(root, text='text')
widget.pack(expand=YES, fill=BOTH)
root.mainloop()

Python tkinter label image not drawn unless a message widget is behind it

I have a transparent tkinter message widget and a label, one containing text the other an image, the image is only drawn in the parts where the text label is behind it. 1
I'm using python tkinter on windows 7 to draw the labels on the desktop on a transparent window, so what you're seeing in the background is my regular windows desktop, which might have something to do with it
Here are snippets of code, but there is alot more that's not relevant I think
x = Tk()
label = tkinter.Message(x, textvariable=text, font=('Terminal','10'), fg='white', bg='green', width=800, anchor='n')
label.master.overrideredirect(True)
label.master.geometry('+30+30')
label.master.lift()
label.master.wm_attributes('-transparentcolor', 'green')
label.pack()
Then this is inside a function which is called to display the plot
new_plot = Label(x, image=plot_image, fg='white', bg='green', anchor='n', width=640, height=480)
new_plot.image = plot_image
new_plot.master.wm_attributes('-transparentcolor', 'green')
new_plot.place(x = 20, y = 30, width=640, height=480)
new_plot.update()
Then at the end
x.mainloop()
I hope this is all that's relevant to the problem
I suspect it has to do with the fact that a tkinter window by default is 1x1 pixel in size. When you use place, tkinter will not expand the window to fit its contents.
The reason it works with the messagebox is because you are adding the messagebox to the root window with pack which will cause the window to grow.
The simple solution is to use new_plot.pack(...) instead of new_plot.place(...).

ttk.ComboBox Styling does not get set properly

I have created a python GUI application. It works great, and I've styled everything to my liking, save for the ComboBox. Styling on the ttk.Combobox doesn't seem to work.
That should give an idea of the material style I'm going for. Here's the styling block I have for the combobox.
globalStyle = ttk.Style()
globalStyle.configure('TCombobox', foreground=textColor, background=backgroundColor, fieldbackground=selectColor, fieldforeground=textColor, font='Verdana')
The only thing I have been able to successfully change is the text and the foreground color. I am looking to edit the following attributes:
Text color
Field background
Dropdown text color
Dropdown background
EDIT: I should mention that the color variables used are all valid hex color codes.
selectColor = '#333333'
backgroundColor = '#444444'
foregroundColor = '#555555'
textColor = '#999999'
So I ran in to the same issue but found most of the solution here. All you have to do is add the following to your code:
option add *TCombobox*Listbox.background color
option add *TCombobox*Listbox.font font
option add *TCombobox*Listbox.foreground color
option add *TCombobox*Listbox.selectBackground color
option add *TCombobox*Listbox.selectForeground color
Then to change the font inside the box (when the drop down isn't present) add font='font_style' to your code.
So in my case I had:
class CreateProfile(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, bg='dodgerblue4')
label = tk.Label(self, text="Create Profile", font=large_font, bg='dodgerblue4', fg='deepskyblue')
label.grid(columnspan=10, row=0, column=0, pady=5, padx=5)
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(1, weight=1)
self.option_add("*TCombobox*Listbox*Background", "dodgerblue")
self.option_add("*TCombobox*Listbox*Font", "pirulen")
self.list_c = ttk.Combobox(self, values=("1", "2", "3", "4"), font='pirulen')
self.list_c.grid(row=1, column=1, pady=5, padx=5)
Make sure you also have the following imports:
import tkinter as tk
import tkinter.ttk as ttk
My issue is I'm only able to change the background color of the actual box (when the drop down isn't present). I'm still trying to figure out how to change the font color (foreground doesn't work for me), and the color of the box itself. So if anybody could add to this answer that would be great!
I know that this question is half a year old, but I had a similar issue and managed to solve it. For changing the color of a ttk Combobox popdown frame you can use the following code:
# these imports are indeed only valid for python 3.x
import tkinter as tk
import tkinter.ttk as ttk
# for python 2.x the following import statements should work:
# import Tkinter as tk
# import ttk
root = tk.Tk()
# adding the options to the root elements
# (all comboboxes will receive this options)
root.option_add("*background", "#444444"),
root.option_add("*foreground", "#999999"),
# create a combobox
ttk.Combobox(root, values=["Banana", "Coconut", "Strawberry"]).pack()
root.mainloop()
I'm not sure whether I understand the styling mechanisms of tk correctly.
At least the above code works for me on Python 3.2 and Python 3.4

Python Tkinter: How do I apply a new background image when opening a new tk window?

I used the code below (with different variable names for each section) to create a background image for each tkinter window. Each of these is initiated in a function and both work fine independently.
When loading one function from another however, the second fails to display an image. (I have tried importing all relevant in each function aswell). It works in the case that use tk.destruct(), however if If I want to keep it open, or hide it with . withdraw(), the image fails to display, rendering the second window useless.
background_image=tk.PhotoImage(...)
background_label = tk.Label(parent, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
Ok I've made up a solution for you. Basically all you need is to use tk.Toplevel() for the second tkinter window and make sure that the 'parent' is root2 so the image will appear in the second window.
I have used buttons for the images, you had labels so you may wish to change this, but buttons gave me a way to open a new tk window easily, I have also used .pack(), not .place(), as it was faster for me. May also be helpful for you to know that I used python 3.3 with windows so you might need a capital T for tkinter.
import tkinter as tk
root1 = tk.Tk()
def new_window():
root2 = tk.Toplevel()
# click the last button and all tk windows close
def shutdown():
root1.destroy()
root2.destroy()
background_image2 = tk.PhotoImage(file = '...')
background_button2 = tk.Button(root2, image = background_image2, command = shutdown)
background_button2.pack()
root2.mainloop()
background_image1 = tk.PhotoImage(file = '...')
# have used a button not a label for me to make another tk window
background_button1 = tk.Button(root1, image = background_image1, command = new_window)
background_button1.pack()
root1.mainloop()
#user2589273 Next time you should add more code so answers can be easily given, and tailored to you, just a suggestion. Hope this helps.

Categories