Python Tkinter 将文本移动到按钮中心,但将图像保留在左上角

问题描述 投票:0回答:2

我想将文本移动到按钮的中心,但将图像保留在左上角。
有人知道这是否可能吗?

下面是我的代码,将图像放置在左上角,将文本放置在左侧,但我无法找到将文本放置在按钮中间的方法。

import tkinter as tk
from tkinter import messagebox
from tkinter import font as tkFont
from PIL import Image, ImageTk

 
# Create the master object
root = tk.Tk()
 
# Sets the window size as "300x300"
root.geometry("300x300")
helv32 = tkFont.Font(family='Helvetica', size=32, weight='bold')
 
# This is the button callback function
# This must be visible to the button, so we must define it before the button widget!
def buttonCallback():
    messagebox.showinfo("Message", "You have clicked the Button!")
 
# Create a tk.PhotoImage
my_image = Image.open("./debian.png")
# Resize it to fit button dimensions
my_image = my_image.resize((25, 25), Image.Resampling.LANCZOS)
# Finally, get the PhotoImage object
my_image = ImageTk.PhotoImage(my_image)
 
# Create a Button widget
button = tk.Button(root, text=" Click", image=my_image, command=buttonCallback, compound=tk.LEFT, height = 300, width = 300, bg="lightblue",
                   font=helv32, anchor=tk.NW)
  
# Use the grid geometry manager to put the widgets in the respective position
button.grid(row=1, column=0)
 
# The application mainloop
root.mainloop()
python-3.x tkinter button
2个回答
0
投票

您可以创建一个更大的空白图像(大约按钮的大小)并将小图像放在左上角。然后在按钮中使用这个组合图像。

下面是示例代码:

import tkinter as tk
from PIL import Image, ImageTk

root = tk.Tk()

helv32 = ("Helvetica", 32, "bold")

# load the required image and resize it to the desired size
logo = Image.open("debian.png").resize((50, 50))
# create a larger transparent image (around the size of the button)
img = Image.new("RGBA", (250, 250), (0, 0, 0, 0))
# paste the small image at the top-left corner of this large image
img.paste(logo)

tkimg = ImageTk.PhotoImage(img)
button = tk.Button(root, text="Click", image=tkimg, compound="c",
                   width=300, height=300, bg="lightblue", font=helv32)
button.pack(padx=10, pady=10)

root.mainloop()

输出:


0
投票

acw1668,我尝试按照你的建议并想出了以下代码。

#!/usr/bin/env python

import tkinter as tk
from PIL import Image, ImageTk, ImageColor

root = tk.Tk()

root.update_idletasks()

root.wm_state("zoomed")
buttonWidth = root.winfo_width()
buttonHeight = root.winfo_height()

screenWidth = root.winfo_screenwidth()
screenHeight = root.winfo_screenheight()
screenText = f'Screen Width: {screenWidth}\nScreen Height: {screenHeight}'


def OnEnter(event, color: str):
    event.widget['background'] = color

def OnLeave(event, color):
    event.widget['background'] = color


def OnButtonResize(event, logoFile: str, imageWidth: int, imageHeight: int):

    buttonWidth = event.width
    buttonHeight = event.height

    # load the required image and resize it to the desired size
    logo = Image.open(logoFile).resize((imageWidth, imageHeight))
    # create a larger transparent image (around the size of the button)
    img = Image.new("RGBA", (buttonWidth, buttonHeight), (0, 0, 0, 0))
    # paste the small image at the top-left corner of this large image
    img.paste(logo)
    
    imgWidth, imgHeight = img.size
    buttonText = f'Button Width: {imgWidth}\nButton Height: {imgHeight}\n{screenText}'
    #print(buttonText)

    tkimg = ImageTk.PhotoImage(img)
    
    event.widget['text'] = buttonText
    event.widget['image'] = tkimg


def Rgb2Hex(rgbTuple: tuple) -> str:
    return (f"#{rgbTuple[0]:02x}{rgbTuple[1]:02x}{rgbTuple[2]:02x}")


def Hex2Rgb(hexcode: str) -> tuple:
    return(ImageColor.getcolor(hexcode, "RGB"))


def clamp(x: int) -> int: 
  return max(0, min(x, 255))


def LightenHexColor(hexColorCode: str , percent: int = 10) -> str:
    
    inputColorTuple = Hex2Rgb(hexColorCode)
    
    ligtherColorTuple = ()
    for i in inputColorTuple:
        ligtherColorTuple = ligtherColorTuple + (clamp(int(i*(100+percent)/100)),)

    return(Rgb2Hex(ligtherColorTuple))


helv32 = ("Helvetica", 32, "bold")

global logo
global img
global tkimg
global button

logoFilename = "debian.png"
logoWidth = logoHeight = 300

# load the required image and resize it to the desired size
logo = Image.open(logoFilename).resize((logoWidth, logoHeight))
# create a larger transparent image (around the size of the button)
#img = Image.new("RGBA", (imageWidth, imageHeight), (0, 0, 0, 0))
# paste the small image at the top-left corner of this large image
#img.paste(logo, (int(imageSize/2), int(imageSize/2)))

tkimg = ImageTk.PhotoImage(logo)
bgColorCursorOut = "#F00000"
bgColorCursorIn = LightenHexColor(bgColorCursorOut)

button = tk.Button(root, text=screenText, image=tkimg, compound="c", bg=bgColorCursorOut, font=helv32, width=buttonWidth, height=buttonHeight)
#button = tk.Button(root, text=screenText, bg="lightblue", font=helv32, width=screenWidth, height=screenHeight)
button.pack(padx=10, pady=10)

button.bind("<Configure>", lambda event: OnButtonResize(event, logoFilename, logoWidth, logoHeight))
button.bind("<Enter>", lambda event: OnEnter(event, bgColorCursorIn))
button.bind("<Leave>", lambda event: OnLeave(event, bgColorCursorOut))

root.mainloop()

如果我注释掉该行,一切似乎都工作正常

event.widget['image'] = tkimg

但是使用该行后,我收到以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\Users\psestini\AppData\Local\Temp\ipykernel_40344\3920381195.py", line 27, in <lambda>
    button.bind("<Enter>", lambda event: OnEnter(event, bgColorCursorIn))
  File "C:\Users\psestini\AppData\Local\Temp\ipykernel_40344\1042462112.py", line 2, in OnEnter
    event.widget['background'] = color
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1686, in __setitem__
    self.configure({key: value})
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1675, in configure
    return self._configure('configure', cnf, kw)
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1665, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: image "pyimage55" doesn't exist
Exception in Tkinter callback
Traceback (most recent call last):
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\Users\psestini\AppData\Local\Temp\ipykernel_40344\3920381195.py", line 28, in <lambda>
    button.bind("<Leave>", lambda event: OnLeave(event, bgColorCursorOut))
  File "C:\Users\psestini\AppData\Local\Temp\ipykernel_40344\1042462112.py", line 5, in OnLeave
    event.widget['background'] = color
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1686, in __setitem__
    self.configure({key: value})
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1675, in configure
    return self._configure('configure', cnf, kw)
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1665, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: image "pyimage55" doesn't exist
Exception in Tkinter callback
Traceback (most recent call last):
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\Users\psestini\AppData\Local\Temp\ipykernel_40344\3920381195.py", line 27, in <lambda>
    button.bind("<Enter>", lambda event: OnEnter(event, bgColorCursorIn))
  File "C:\Users\psestini\AppData\Local\Temp\ipykernel_40344\1042462112.py", line 2, in OnEnter
    event.widget['background'] = color
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1686, in __setitem__
    self.configure({key: value})
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1675, in configure
    return self._configure('configure', cnf, kw)
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1665, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: image "pyimage55" doesn't exist
Exception in Tkinter callback
Traceback (most recent call last):
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\Users\psestini\AppData\Local\Temp\ipykernel_40344\3920381195.py", line 28, in <lambda>
    button.bind("<Leave>", lambda event: OnLeave(event, bgColorCursorOut))
  File "C:\Users\psestini\AppData\Local\Temp\ipykernel_40344\1042462112.py", line 5, in OnLeave
    event.widget['background'] = color
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1686, in __setitem__
    self.configure({key: value})
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1675, in configure
    return self._configure('configure', cnf, kw)
  File "E:\Programs\Anaconda3\lib\tkinter\__init__.py", line 1665, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: image "pyimage55" doesn't exist

您对我的错误有什么建议以及如何修改代码以避免它吗?

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.