Python - 在动态按钮后面添加图片和命令
Python - adding pictures and commands behind dynamic buttons
我对 python 和 RPi 很陌生。我正在尝试根据 MySQL 查询生成动态按钮。我在论坛中找到了这个帖子:How to create a self resizing grid of buttons in tkinter?
了解如何在网格中生成动态按钮很有帮助。尽管如此,我在为每个动态按钮和图片输入命令时遇到问题。
这是我的代码:
from __future__ import division
import tkinter as tk
from tkinter import *
import MySQLdb
db = MySQLdb.connect("localhost", "User...", "SecurePW", "myCoolDB")
curs=db.cursor()
PhotoImageFolder='/home/pi/App/CocktailPic/'
root = Tk()
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(root, 0, weight=1)
#Create & Configure frame
frame=Frame(root)
frame.grid(row=0, column=0, sticky=N+S+E+W)
curs.execute("SELECT * FROM `CockRec` WHERE `IsACTIVE`=1")
max_col_index=10
col_index=0
row_index=0
def CocktailBtnCmd(Cocktail_ID):
messagebox.showinfo(title='Informatio', message=Cocktail_ID)
#print("Cocktail ID: ",Cocktail_ID)
for entry in curs.fetchall():
if col_index>=max_col_index:
row_index=row_index+1
col_index=0
CocktailID=entry[0]
Cocktail=entry[1]
CocktailPicturePath=entry[3]
btn_image=PhotoImage(file = PhotoImageFolder + CocktailPicturePath)
photoImage = btn_image.subsample(10, 10)
Grid.rowconfigure(frame, row_index, weight=1)
Grid.columnconfigure(frame, col_index, weight=1)
btn = Button(frame, text = Cocktail, image=photoImage, command = CocktailBtnCmd(CocktailID)) #create a button
btn.grid(row=row_index, column=col_index, sticky=N+S+E+W)
col_index=col_index+1
问题是,当我 运行 代码时,它只在最后一个按钮上显示图片,而且按钮后面的命令不起作用。
如果我在 For LOOP 之前定义图片,它至少适用于每个按钮上的所有相同图片。
知道吗,我做错了什么?
command=CocktailBtnCmd(CocktailID)
将立即执行 CocktailBtnCmd(...)
并将结果(即 None
)分配给 command
选项。这就是按钮稍后不起作用的原因。
您需要使用 lambda
使用默认值的参数来代替:
command=lambda CocktailID=CocktailID: CocktailBtnCmd(CocktailID)
图片问题,是因为你在for循环中使用了相同的变量来保存图片的引用:
photoImage = btn_image.subsample(2, 2)
所以在for循环之后,只有最后一张图片引用了它,之前的图片将被垃圾回收。
您可以使用相关按钮的属性保留所有图像的引用:
for entry in curs.fetchall():
...
photoImage = btn_image.subsample(2, 2)
...
btn = Button(frame, text = Cocktail, image=photoImage, command=lambda: CocktailID=CocktailID: CocktailBtnCmd(CocktailID))
btn.image = photoImage # use an attribute to keep the reference of image
...
此外,我建议使用官方 mysql.connector
模块而不是 MySQLdb
。
我对 python 和 RPi 很陌生。我正在尝试根据 MySQL 查询生成动态按钮。我在论坛中找到了这个帖子:How to create a self resizing grid of buttons in tkinter?
了解如何在网格中生成动态按钮很有帮助。尽管如此,我在为每个动态按钮和图片输入命令时遇到问题。
这是我的代码:
from __future__ import division
import tkinter as tk
from tkinter import *
import MySQLdb
db = MySQLdb.connect("localhost", "User...", "SecurePW", "myCoolDB")
curs=db.cursor()
PhotoImageFolder='/home/pi/App/CocktailPic/'
root = Tk()
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(root, 0, weight=1)
#Create & Configure frame
frame=Frame(root)
frame.grid(row=0, column=0, sticky=N+S+E+W)
curs.execute("SELECT * FROM `CockRec` WHERE `IsACTIVE`=1")
max_col_index=10
col_index=0
row_index=0
def CocktailBtnCmd(Cocktail_ID):
messagebox.showinfo(title='Informatio', message=Cocktail_ID)
#print("Cocktail ID: ",Cocktail_ID)
for entry in curs.fetchall():
if col_index>=max_col_index:
row_index=row_index+1
col_index=0
CocktailID=entry[0]
Cocktail=entry[1]
CocktailPicturePath=entry[3]
btn_image=PhotoImage(file = PhotoImageFolder + CocktailPicturePath)
photoImage = btn_image.subsample(10, 10)
Grid.rowconfigure(frame, row_index, weight=1)
Grid.columnconfigure(frame, col_index, weight=1)
btn = Button(frame, text = Cocktail, image=photoImage, command = CocktailBtnCmd(CocktailID)) #create a button
btn.grid(row=row_index, column=col_index, sticky=N+S+E+W)
col_index=col_index+1
问题是,当我 运行 代码时,它只在最后一个按钮上显示图片,而且按钮后面的命令不起作用。
如果我在 For LOOP 之前定义图片,它至少适用于每个按钮上的所有相同图片。
知道吗,我做错了什么?
command=CocktailBtnCmd(CocktailID)
将立即执行 CocktailBtnCmd(...)
并将结果(即 None
)分配给 command
选项。这就是按钮稍后不起作用的原因。
您需要使用 lambda
使用默认值的参数来代替:
command=lambda CocktailID=CocktailID: CocktailBtnCmd(CocktailID)
图片问题,是因为你在for循环中使用了相同的变量来保存图片的引用:
photoImage = btn_image.subsample(2, 2)
所以在for循环之后,只有最后一张图片引用了它,之前的图片将被垃圾回收。
您可以使用相关按钮的属性保留所有图像的引用:
for entry in curs.fetchall():
...
photoImage = btn_image.subsample(2, 2)
...
btn = Button(frame, text = Cocktail, image=photoImage, command=lambda: CocktailID=CocktailID: CocktailBtnCmd(CocktailID))
btn.image = photoImage # use an attribute to keep the reference of image
...
此外,我建议使用官方 mysql.connector
模块而不是 MySQLdb
。