我正在编写一个将图像转换为灰度的程序。我已经很好地工作了,现在我正在实现单选按钮,让用户选择使用哪种类型的灰度。到目前为止,我的问题是,当第一次制作单选按钮时,命令=函数会立即被调用,并将我的所有布尔值设置为True,因为这是我明确告诉它的,通过使用function()而不是函数来传递。我正在想一种方法,我可以用它来存储选择的单选按钮,或者希望有一些内置的东西我可以检查。我知道使用全局变量不是最佳实践,并且类会消除它们的必要性。这是相关代码。
# Global variables for radio buttons----
radio1 = False
radio2 = False
radio3 = False
radio4 = False
def whichSelected(numberSelected):
global radio1
global radio2
global radio3
global radio4
if numberSelected == 4:
radio4 = True
if numberSelected == 3:
radio3 = True
if numberSelected == 2:
radio2 = True
if numberSelected == 1:
radio1 = True
# Radio Button Code---------------------------------------------------------
var = tkinter.IntVar()
option1 = tkinter.Radiobutton(window, text ='Average Grayscale',variable = var, value = 1,command = whichSelected(1))
option2 = tkinter.Radiobutton(window, text ='Lightness Grayscale',variable = var, value = 2, command = whichSelected(2))
option3 = tkinter.Radiobutton(window, text ='Luminosity Grayscale',variable = var, value = 3, command = whichSelected(3))
option4 = tkinter.Radiobutton(window, text ='Invert',variable = var, value = 4, command = whichSelected(4))
def change_pixel():
global tkPic2
global radio1
global radio2
global radio3
global radio4
# Treats the image as a 2d array, iterates through changing the
#values of each pixel with the algorithm for gray
rgbList = pic.load() #Get a 2d array of the pixels
for row in range(picWidth):
for column in range(picHeight):
rgb = rgbList[row,column]
r,g,b = rgb # Unpacks the RGB value tuple per pixel
if radio1 == True:
grayAlgorithm1 = grayAverage(r,g,b)
rgbList[row,column] = (grayAlgorithm1, grayAlgorithm1, grayAlgorithm1)
elif radio2 == True:
grayAlgorithm = lightness(r,g,b)
rgbList[row,column] = (grayAlgorithm1, grayAlgorithm1, grayAlgorithm1)
elif radio3 == True:
grayAlgorithm1= luminosity(r,g,b)
rgbList[row,column] = (grayAlgorithm1, grayAlgorithm1, grayAlgorithm1) # Gives each pixel a new RGB value
elif radio4 == True:
r,g,b= invertRGB(r,g,b)
rgbList[row,column] = (r, g, b) # Gives each pixel a new RGB value
# Converting to a tkinter PhotoImage
tkPic2 = ImageTk.PhotoImage(pic, master = window)
print(radio1,radio2,radio3,radio4)
canvas1.create_image(815,170, anchor='e',image = tkPic2)
我不完全确定您为什么首先需要whichSelected
。您应该能够从var
:的值中判断出来
value = var.get()
if value == 1:
print "Average Grayscale"
elif value == 2:
print "Lightness Grayscale"
...
这还有一个额外的好处,可以保证您知道当前检查了哪个值。使用前面的方法,您需要添加一些逻辑,以便在生成所需的True
之前,将所有全局变量都转换为False
。按照您的功能,如果用户选择其中一个单选按钮,然后选择另一个,则在全局变量中,这两个按钮都将标记为True
。
然而,指出为什么您的方法也失败是很有启发性的。除了前面提到的问题,command
参数应该是一个函数,您正在传递函数果(在本例中为None
)。当您调用函数以获得结果时,您将全局设置为True
作为副作用。
快速解决方法是使用lambda
创建一个新函数,该函数以您想要的方式调用旧函数。这样,您将推迟将全局设置为True
,直到您的单选按钮被实际点击:
option1 = tkinter.Radiobutton(window, text='Average Grayscale',
variable=var,
value=1,
command=lambda: whichSelected(1))
lambda
最终在tkinter
应用程序中对这类事情非常有用。(我无法想象在没有它的情况下编写应用程序…)