python-3.x - 使用 tkinter、MVC 和 Observables 设置 Entry 的值

标签 python-3.x user-interface model-view-controller tkinter

我正在尝试使用 tkinter 构建一个简单的 GUI 来读取 CSV,然后运行一些文本挖掘函数。我很难理解 tkinter 的回调函数。以下代码是使用此 ToyMVC 代码创建的。

我能够弹出 GUI,但在用户按下按钮后无法让最右侧的 Entry 小部件(变量名称 = FinalPathEntry)更新为左侧小部件中用户输入的文本。

我非常感谢任何关于如何前进以及我做错了什么的建议。

最好,

import tkinter as tk

class Observable:
    def __init__(self, initialValue=None):
        self.data = initialValue
        self.callbacks = {}

def addCallback(self, func):
    self.callbacks[func] = 1

def delCallback(self, func):
    del self.callback[func]

def _docallbacks(self):
    for func in self.callbacks:
         func(self.data)

def set(self, data):
    self.data = data
    self._docallbacks()

def get(self):
    return self.data

def unset(self):
    self.data = None


class Model:
    def __init__(self):
        self.csvPath = Observable("")

    def addPath(self, value):
        self.csvPath.set(self.csvPath.get())


class View(tk.Toplevel):
    def __init__(self, master):
        tk.Toplevel.__init__(self, master)
        self.protocol('WM_DELETE_WINDOW', self.master.destroy)
        tk.Label(self, text='Please input path to CSV').pack(side='left')

        self.pathEntry = tk.Entry(self, width=50)
        self.pathEntry.pack(side='left')
        self.addButton = tk.Button(self, text='Read CSV', width=8)
        self.addButton.pack(side='left')
        self.path = tk.StringVar()
        self.finalPathEntry = tk.Entry(self, width = 30, textvariable = self.path)
        self.finalPathEntry.pack(side='left')

    def setPath(self, value):
        self.path.set(str(value)) 


class Controller:
    def __init__(self, root):
        self.model = Model()
        self.model.csvPath.addCallback(self.pathChanged)
        self.view1 = View(root)
        self.view1.minsize(width = 500, height = 500)
        self.view1.addButton.config(command=self.addPath)
        self.pathChanged(self.model.csvPath.get())

    def addPath(self):
        self.model.addPath(self.view1.pathEntry.get())

    def pathChanged(self, val):
        self.view1.setPath(val)


if __name__ == '__main__':
    root = tk.Tk()
    root.withdraw()
    app = Controller(root)
    root.mainloop()

编辑:使用下面的答案,我已经修复了我的代码。这是更新后的工作片段:

import tkinter as tk

class Observable:
    def __init__(self, initialValue = None):
        self.data = initialValue
        self.callbacks = {}

    def addCallback(self, func):
        self.callbacks[func] = 1

    def delCallback(self, func):
        del self.callback[func]

    def _docallbacks(self):
        for func in self.callbacks:
            func(self.data)

    def set(self, data):
        self.data = data
        self._docallbacks()

    def get(self):
        return self.data

    def unset(self):
        self.data = None

class Model:
    def __init__(self):
        self.csvPath = Observable("")

    def addPath(self, value):
        self.csvPath.set(self.csvPath.get())

class View(tk.Toplevel):
    def __init__(self, master):
        tk.Toplevel.__init__(self, master)
        self.protocol('WM_DELETE_WINDOW', self.master.destroy)
        tk.Label(self, text='Please input path to CSV').pack(side='left')
        self.pathEntry = tk.Entry(self, width=50)
        self.pathEntry.pack(side='left')
        self.addButton = tk.Button(self, text='Read CSV', width=8)
        self.addButton.pack(side='left')
        self.path = tk.StringVar()
        self.finalPathEntry = tk.Entry(self, width = 30, textvariable = self.path)
        self.finalPathEntry.pack(side='left')

    def setPath(self, value):
        self.path.set(str(value))

class Controller:
    def __init__(self, root):
        self.model = Model()
        self.model.csvPath.addCallback(self.pathChanged)
        self.view1 = View(root)
        self.view1.minsize(width = 500, height = 500)
        self.view1.addButton.config(command = self.addPath)
        self.pathChanged(self.model.csvPath.get())

    def addPath(self):
        self.model.addPath(self.view1.pathEntry.get())

    def pathChanged(self, val):
        self.view1.setPath(val)

if __name__ == '__main__':
    root = tk.Tk()
    root.withdraw()
    app = Controller(root)
    root.mainloop()

最佳答案

关于这段代码的一件事似乎很明显:从

开始的函数
def addcallback(self, func): 

直到

def unset(self):

不是 Observable 类的一部分。所以“ self ”论证并不是你所期望的那样。您应该缩进这些函数。

关于python-3.x - 使用 tkinter、MVC 和 Observables 设置 Entry 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38579926/

相关文章:

model-view-controller - 为什么 Qt 滥用模型/ View 术语?

spring - 如何访问 Spring MVC Controller 类中的自定义 bean?

python 3 : receive user input including newline characters

django - 如何使用 Django-Tables2 导出 .csv?

python - PyCharms 索引目录由什么决定

python 打开一个包含整数的文件

python - Tkinter 多项操作

java - 在 Java 中创建 GUI 时出现编译错误

user-interface - 皮肤 vs 主题,有什么区别?

model-view-controller - MVC 框架中 Index.php 的用途是什么?