Как получить переменную и показать результат в приложении tkinter, решив уравнение с двумя переменными из трех - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь создать приложение с графическим интерфейсом с tkinter, которое принимает две переменные из трех. Я создал виджеты для переменной, но теперь хочу получить переменную из виджетов. Так что я могу выполнить функцию решения. А также хочет напечатать решение в виджете scrolledtext.

Справка очень ценится, так как я изучаю GUI на питоне.

Вот мой код:

import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext


class LabelInput(tk.LabelFrame):
    def __init__(self, parent, label='', input_class=ttk.Entry, input_var=None, input_args=None, label_args=None,
                 **kwargs):
        super().__init__(parent, **kwargs)
        input_args = input_args or {}
        label_args = label_args or {}
        self.variable = input_var

        self.label = ttk.Label(self, text=label, **label_args)
        self.label.grid(row=0, column=0, sticky=tk.EW, padx=3)

        self.input = input_class(self, **input_args)
        self.input.grid(row=1, column=0, sticky=tk.EW, padx=3)

        self.columnconfigure(0, weight=1)

    def grid(self, sticky=tk.EW, **kwargs):
        super().grid(sticky=sticky, **kwargs)


class InfoFrame(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        massinfo = tk.LabelFrame(self, text='Mass')
        self.inputs = {}
        self.inputs['Mass'] = LabelInput(massinfo, 'Mass', input_var=tk.DoubleVar())
        self.inputs['Mass'].grid(row=0, column=0)
        massinfo.grid(row=0, column=0, sticky=tk.EW, padx=3)

        volumeinfo = tk.LabelFrame(self, text='Volume')
        self.inputs['Volume'] = LabelInput(volumeinfo, 'Volume', input_var=tk.DoubleVar())
        self.inputs['Volume'].grid(row=0, column=0)
        volumeinfo.grid(row=0, column=1, sticky=tk.EW, padx=3)

        densityinfo = tk.LabelFrame(self, text='Density')
        self.inputs['Density'] = LabelInput(densityinfo, 'Density', input_var=tk.DoubleVar())
        self.inputs['Density'].grid(row=0, column=0)
        densityinfo.grid(row=0, column=2, sticky=tk.EW, padx=3)

        # output
        outputinfo = tk.LabelFrame(self, text='Solution')
        self.solution = scrolledtext.ScrolledText(outputinfo, width=75, height=25, wrap=tk.WORD)
        self.solution.grid(row=0, column=0)
        outputinfo.grid(row=1, column=0, columnspan=3)

    # getting the data
    def get(self):
        data = {}
        for key, widget in self.inputs.items():
            data[key] = widget.get()
        return data


class Application(tk.Tk, InfoFrame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.infoframe = InfoFrame(self)
        self.infoframe.grid(row=0, padx=10)

        # Buttons
        self.findbutton = ttk.Button(self, text='Find', command=self.on_find)
        self.findbutton.grid(row=1, sticky=tk.W, padx=5)
        self.clearbutton = ttk.Button(self, text='Clear', command=self.on_clear)
        self.clearbutton.grid(row=1, column=0, sticky=tk.E, padx=5)
        self.exitbutton = ttk.Button(self, text='Exit', command=self.on_exit)
        self.exitbutton.grid(row=1, column=0, padx=5)

    def on_find(self):
        pass

    def on_clear(self):
        pass

    def on_exit(self):
        pass


app = Application()
app.mainloop()

1 Ответ

0 голосов
/ 02 октября 2019

Добро пожаловать в Stackoverflow.

В основном класс LabelInput нуждается в методе get. Вызовы get in InfoFrame попадают в LabelFrame, а не в Entry внутри него. Также легко определить метод set, чтобы он был добавлен.

class LabelInput(tk.LabelFrame):
    def __init__(self, parent, label='', input_class=ttk.Entry, input_var=None, input_args=None, label_args=None,
                 **kwargs):
        super().__init__(parent, **kwargs)
        input_args = input_args or {}
        label_args = label_args or {}
        self.variable = input_var

        self.label = ttk.Label(self, text=label, **label_args)
        self.label.grid(row=0, column=0, sticky=tk.EW, padx=3)

        self.input = input_class(self, **input_args)
        self.input.grid(row=1, column=0, sticky=tk.EW, padx=3)
        # ***********************************************
        self.input.config(textvariable=self.variable)  
        # This links the self.variable to the input text variable. 

        self.columnconfigure(0, weight=1)

    def grid(self, sticky=tk.EW, **kwargs):
        super().grid(sticky=sticky, **kwargs)

    def get(self): return self.variable.get()       # New
    def set(self, v): self.variable.set(v)          # New

Как только он будет сделан, метод on_find может использовать info.frame.get () для загрузки трех входных переменных. Как именно это должно выглядеть, не ясно, но вот простой вариант.

    def on_find(self):
        data = self.infoframe.get()
        if data['Mass'] == 0.0:
            res = 'Mass is {}'.format(data['Volume']*data['Density'])
        elif data['Volume'] == 0.0:
            res = 'Volume is {}'.format(data['Mass'] / data['Density'])
        elif data['Density'] == 0.0:
            res = 'Density is {}'.format(data['Mass'] / data['Volume'])
        else:
            res = 'At least one input field must be zero.'
        self.infoframe.solution.delete(1.0, tk.END )
        self.infoframe.solution.insert(1.0, res)

Это все равно не удастся для деления на ноль, но показывает извлечение входных данных и размещение результатов в текстовом поле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...