从tkinter中的另一个窗口获取输入

2024-05-23 19:16:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做的这个项目有点麻烦。我的项目就是这个GUI应用程序。在test.py文件中,我调用另一个文件,该文件包含另一个GUI窗口的说明。这就是我遇到麻烦的地方。在test.py文件中,如果单击“运行”,将出现一个小窗口。在小窗口中单击测试。如果在窗口的文本字段中输入数字,然后单击enter,则会出现另一个包含文本字段的窗口。我的IDE会收到这些错误消息。它说“ValueError:无法将字符串转换为float:”“”我的问题是如何修复此问题,以避免收到此错误消息?它应该打印输入到窗口中的输入。我有两个文件,test.py和model_objects.py。如果您单独运行model_objects.py,它将非常有效。但是,当我尝试将此文件导入test.py时,它不想正常工作。这是用Python编程的。此外,我的model_objects.py文件位于项目中名为util的文件夹中。我输入的值是浮点值。我在这方面遇到了麻烦。如果你能帮忙,我将不胜感激

这是我的密码:

model_objects.py(位于项目中名为util的文件夹中)


import tkinter as tk
from tkinter import ttk
from tkinter.ttk import Style

import numpy as np

from util import InputData


class Harmonic_Oscillator:
    def __init__(self):
        self.type = 0
        self.name = "Harmonic Oscillator"
        self.nparam = 2
        self.label = ["\u03BC", "k"]
        self.param = np.zeros(self.nparam, float)

    def set_param(self, param_list):
        for i in range(self.nparam):
            self.param[i] = param_list[i]
        return


class Morse_Oscillator:
    def __init__(self):
        self.type = 1
        self.name = "Morse Oscillator"
        self.nparam = 3
        self.label = ["\u03BC", "De", "a"]
        self.param = np.zeros(self.nparam, float)

    def set_param(self, param_list):
        for i in range(self.nparam):
            self.param[i] = param_list[i]
        return


class Test_Oscillator:
    def __init__(self):
        self.type = 2
        self.name = "Test Oscillator"
        self.nparam = 4
        self.mu = 0
        self.label = ["a", "b", "c", "d"]
        self.param = np.zeros(self.nparam, float)

    def set_param(self, param_list):
        for i in range(self.nparam):
            self.param[i] = param_list[i]
        return


def model_prompt(potential_model):
    window1 = tk.Tk()
    style = Style()
    window1.title('PyFGH Parameters')
    box_length = 103
    for q in range(3):
        box_length = box_length + 33 * potential_model[q].nparam
    box_len_str = '300x' + str(box_length)
    window1.geometry(box_len_str)

    entries = []
    qvar = np.empty(3, dtype=list)
    for i in range(3):
        qvar[i] = []
    j = 0
    y = 5

    for q in range(3):
        for qparam in range(potential_model[q].nparam):
            qvar[q].append(tk.StringVar())

            ttk.Label(window1, text=potential_model[q].label[qparam] + " for Q:" + str(q + 1) + ":",
                      font=("Times New Roman", 15)).place(x=50, y=y)
            # set text variable as q1var[j] , each entry will have separate index in the list
            a1 = ttk.Entry(window1, textvariable=qvar[q][qparam], font=("Times New Roman", 10)).place(x=140, y=y)

            j += 1
            y += 35

    def enter_button():
        for q in range(3):
            param_list = []
            for qparam in range(potential_model[q].nparam):
                param_list.append(qvar[q][qparam].get())
            potential_model[q].set_param(param_list)  # This is giving me error. Not working properly!!!

        for q in range(3):
            for qparam in range(potential_model[q].nparam):
                print(potential_model[q].param[qparam])

        InputData.output.items.model_data = potential_model
        print(InputData.output.items.model_data)
        window1.destroy()

    enter = tk.Button(window1, text='Enter', bd='20', bg='green', fg='white',
                      command=enter_button).place(x=110, y=y)

    window1.mainloop()


def output2():
    sections = []
    for i in range(3):
        if InputData.output.items.v[i] == "Model-Harmonic Oscillator":
            sections.append(Harmonic_Oscillator())
        elif InputData.output.items.v[i] == "Model-Morse Oscillator":
            sections.append(Harmonic_Oscillator())
        elif InputData.output.items.v[i] == "Model-Test Oscillator":
            sections.append(Harmonic_Oscillator())


#test = [Harmonic_Oscillator(), Morse_Oscillator(), Test_Oscillator()]
#model_prompt(test)

下面是另一个名为test.py的文件

from util import InputData
from util import model_objects
from util import model_objects
from util.model_objects import Harmonic_Oscillator, Morse_Oscillator, Test_Oscillator, model_prompt
import tkinter as tk


def write_slogan():
    test = [Harmonic_Oscillator(), Morse_Oscillator(), Test_Oscillator()]
    model_prompt(test)


root = tk.Tk()
frame = tk.Frame(root)
frame.pack()

button = tk.Button(frame,
                   text="QUIT",
                   fg="red",
                   command=quit)
button.pack(side=tk.LEFT)
slogan = tk.Button(frame,
                   text="TEST",
                   command=write_slogan)
slogan.pack(side=tk.LEFT)

root.mainloop()

Tags: inpytestimportselfformodelparam
2条回答

我举了一个小例子,我希望它符合你的主要问题。如果要使用类,在大多数情况下需要引用

from tkinter import *


class MainWindow(Tk):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.test = Test(self) # test class import

        self.outputLbl = Label(self) # output Label 
        self.outputLbl.pack(side="top", fill="x", ipady=20)


class Test(Frame):
    def __init__(self, parent):
        super(Test, self).__init__()
        self.parent = parent # you can use this way to call between classes

        self._input = Entry(self.parent) 
        self._input.pack()
        self._input.bind("<Return>", self.outputMW)

    def outputMW(self, event):  # function, when pressing return it gives changes the text in your label
        var = self._input.get()
        self.parent.outputLbl.config(text=var)  # self.parent makes the reference to your other class


if __name__ == '__main__':
    mw = MainWindow()
    mw.geometry("500x500")
    mw.mainloop()

这有点深奥,但问题是model_prompt函数中的这一行:

qvar[q].append(tk.StringVar())

快速解决办法是:

qvar[q].append(tk.StringVar(window1))

tkinter变量类型的构造函数接受一个可选参数——关联条目小部件所连接窗口的句柄。如果没有提供,默认情况下,它将选择实例化的第一个tk.Tk窗口(在您的示例中,这是test.py中的root)。每当绑定窗口的事件队列被清除时,StringVar将更新自身。由于生成了一个新的tk.Tk,这会中断root事件队列,并且由于变量已绑定到root,因此即使在条目中输入了文本,它们也不会更新

如果你想变得超级正派,你应该查看tk.Topleveltkinter.simpledialog来生成子窗口。首先,您的程序不应该有多个tk.Tk窗口

相关问题 更多 >