在GUI中使用函数 - 如何将变量传递给小部件

时间:2016-05-17 01:46:39

标签: python tkinter

已解决 - 回答@ How to take input from Tkinter

ONE GOTCHA - 我尝试在已解决的链接中复制示例的样式,尽管我保留了一些自己的格式。我发现如果获得返回值的对象是在添加了任何其他点的情况下创建的,例如将 .pack()或在我的情况下 .grid()在创建对象的同一行上,当您尝试将变量传回时会抛出错误。因此,请继续使用第二行 .pack() .grid()

原始帖子

我有一个在命令行上工作正常的程序,我试图给它一个GUI。不幸的是,我仍然对如何在界面中使用函数/方法/命令感到困惑。

我的例子是在从用户那里获得输入后使用按钮来使所有内容滚动。在命令行程序中,它是作为变量传递给一个函数的用户输入,并返回其他三个变量。这三个变量被传递给另一个函数以提供结果,然后将结果格式化为显示。

好吧,我试图使用tkinter。我有一个输入字段,用于将用户输入分配给变量。我有一个链接到一个函数的按钮,该函数用于启动滚动...我不知道如何将该变量发送到所需的函数,或者如何获取返回的变量并应用它。在我的具体例子中,我想发送变量"符号"对函数" parse()"," parse()"的输出将被发送到" roll()",以及" roll()"的输出发送到变量"输出"然后显示。所有这一切都将使用带有" command = calculate"的按钮开始,使用" calculate()"是一个让整个球滚动的功能。

我非常抱歉......我完全是自学成才,而且我确信我甚至没有使用正确的术语。我也明白这个例子不是非常pythonic - 我最终会把所有这些都放到类中并将函数更改为方法,但是现在我只想看看它的工作原理。

到目前为止,这是代码。公平的警告,这不是我遇到的唯一问题......我只想坚持一个问题,直到我能解决它。

#!/usr/bin/env python

from tkinter import *
from tkinter import ttk
import re
import random

# Parsing function from the original command line tool
# Turns dice notation format into useful variables

def parse(d):
    dice, dtype_mod = d.split('d')

    dnum = 1
    dtype = 6
    mod = 0

    if dtype_mod:
        if '-' in dtype_mod:
            dtype, mod = dtype_mod.split('-')
            mod = -1 * int(mod)
        elif '+' in dtype_mod:
            dtype, mod = dtype_mod.split('+')
            mod = int(mod)
        else:
            dtype = dtype_mod
    if not dtype: dtype = 6
    if not mod: mod = 0

    return (int(dice), int(dtype), int(mod))

# Rolling function from the original command line tool
# 'print()' will be changed into a variable, with the output 
# appended in the working version.

def roll(a, b):
    rolls = []
    t = 0

    for i in range(a):
        rolls.append(random.randint(1, b))
        t += int(rolls[i])
        print(('Roll number %d is %s, totaling %d') % (i + 1, rolls[i], t))
    return (int(t))

# Placeholder - the rest of the command line code will be used here later
# This code will be what starts everything rolling.
# For debugging, attempting to pass a variable, doing it wrong.

def calculate():
    output = "this is something different"
    return output

# Initialize

dice = Tk()
dice.title('Roll the Dice')
dice.geometry("800x600+20+20")

# Drawing the main frame

mainframe = ttk.Frame(dice, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

# Variables needed for program and widgets

random.seed()
notation = ""
output = """This is
an example of a lot of crap
that will be displayed here
if I ever get
this to work
and this is a really long line -Super Cali Fragil Istic Expi Ali Docious
"""

# Dice notation entry field, and it's label

notation_entry = ttk.Entry(mainframe, width=10, textvariable=notation)
notation_entry.grid(column=2, row=1)
ttk.Label(mainframe, text="Dice").grid(column=1, row=1)

# Section used for output
"""Huge laundry list of problems here:

1.  textvariable is not displaying anything here.  If I change it to text
    it seems to work, but from what I can tell, that will not update.
2.  I would love for it to have a static height, but height is not allowed here.
    Need to figure out a workaround.
3.  Also, have not figured out how to get the value returned by calculate()
    to show up in here when the button is pressed..."""

output_message = Message(mainframe, textvariable=output, width= 600)
output_message.grid(column=1, row=2, rowspan=3, columnspan=3)

# The 'make it go' button.
"""Can I pass the function a variable?"""

ttk.Button(mainframe, text="Roll!", command=calculate).grid(column=3, row=5)


# This is a bunch of stuff from the command line version of this program.
# Only here for reference

"""while True:
    notation = raw_input('Please input dice notation or q to quit: ')

    if notation == "q":
        raise SystemExit
    else:
         print(notation)

        numbers = parse(notation)
        (dice, dtype, mod) = numbers

        total = roll(dice, dtype)
        total += mod

        print('Your total is %d' % total)"""


dice.mainloop()

1 个答案:

答案 0 :(得分:0)

当您在创建对象时使用textvariable时需要使用字符串变量而不是普通的字符串变量,我将变量表示法更改为字符串变量

notation = StringVar()
notation.set("")

然后在我使用的计算子中获取符号的值

print(notation.get())

我编辑的代码已完全粘贴

#!/usr/bin/env python

from tkinter import *
from tkinter import ttk
import re
import random

# Parsing function from the original command line tool
# Turns dice notation format into useful variables

def parse(d):
    dice, dtype_mod = d.split('d')

    dnum = 1
    dtype = 6
    mod = 0

    if dtype_mod:
        if '-' in dtype_mod:
            dtype, mod = dtype_mod.split('-')
            mod = -1 * int(mod)
        elif '+' in dtype_mod:
            dtype, mod = dtype_mod.split('+')
            mod = int(mod)
        else:
            dtype = dtype_mod
    if not dtype: dtype = 6
    if not mod: mod = 0

    return (int(dice), int(dtype), int(mod))

# Rolling function from the original command line tool
# 'print()' will be changed into a variable, with the output 
# appended in the working version.

def roll(a, b):
    rolls = []
    t = 0

    for i in range(a):
        rolls.append(random.randint(1, b))
        t += int(rolls[i])
        print(('Roll number %d is %s, totaling %d') % (i + 1, rolls[i], t))
    return (int(t))

# Placeholder - the rest of the command line code will be used here later
# This code will be what starts everything rolling.
# For debugging, attempting to pass a variable, doing it wrong.

def calculate():
    print(notation.get())
    output = "this is something different"
    return output

# Initialize

dice = Tk()
dice.title('Roll the Dice')
dice.geometry("800x600+20+20")

# Drawing the main frame

mainframe = ttk.Frame(dice, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

# Variables needed for program and widgets

random.seed()
notation = StringVar()
notation.set("")
output = """This is
an example of a lot of crap
that will be displayed here
if I ever get
this to work
and this is a really long line -Super Cali Fragil Istic Expi Ali Docious
"""

# Dice notation entry field, and it's label

notation_entry = ttk.Entry(mainframe, width=10, textvariable=notation)
notation_entry.grid(column=2, row=1)
ttk.Label(mainframe, text="Dice").grid(column=1, row=1)

# Section used for output
"""Huge laundry list of problems here:

1.  textvariable is not displaying anything here.  If I change it to text
    it seems to work, but from what I can tell, that will not update.
2.  I would love for it to have a static height, but height is not allowed here.
    Need to figure out a workaround.
3.  Also, have not figured out how to get the value returned by calculate()
    to show up in here when the button is pressed..."""

output_message = Message(mainframe, textvariable=output, width= 600)
output_message.grid(column=1, row=2, rowspan=3, columnspan=3)

# The 'make it go' button.
"""Can I pass the function a variable?"""

ttk.Button(mainframe, text="Roll!", command=calculate).grid(column=3, row=5)


# This is a bunch of stuff from the command line version of this program.
# Only here for reference

"""while True:
    notation = raw_input('Please input dice notation or q to quit: ')

    if notation == "q":
        raise SystemExit
    else:
         print(notation)

        numbers = parse(notation)
        (dice, dtype, mod) = numbers

        total = roll(dice, dtype)
        total += mod

        print('Your total is %d' % total)"""


dice.mainloop()