【问题标题】:Python integration of Objects in others其他对象的 Python 集成
【发布时间】:2020-12-11 19:32:14
【问题描述】:

修复:我将 Radiobutton 的调用从视图的 init 移动到控制器,如下所示:

class Controller(object):
    def __init__(self):
        self.model = Model()
        print('start init of View')
        self.view = View(self.importieren, self.exportieren, self.beenden, self.J5, self.J6, self.J7, self.J8, self.J9,
                         self.J10, self.J11, self.J12, self.JA, self.tabelle_sorti, self.hinzufugen, self.zuordnen,
                         self.ande, self.JA, self.model.ausgabe('projekte'), self.tabelle_update, self.a1, self.a2, self.a3,
                         self.a4, self.a5, self.a6, self.a7)
        print('done init')
        self.wahlen = ('sErst', 'sZweit', 'sDritt')
        self.delimiter = {'imp_s': None, 'imp_p': None, 'exp': None}
        self.dchosen = None
        self.slcsv = 'schuelerliste.csv'
        self.plcsv = 'projektliste.csv'
        self.double = False
        self.andernx = ""

        self.view.radios['jahrg-Alle'].invoke()
        self.tabelle()
        self.view.table['main'].bind('<Double-Button-1>', self.treevent)
        # Erstimportierung
        if self.model.ausgabe('schueler'):
            self.importieren(True)

        self.view.mainloop()


    def tabelle_update(self, fetchshlr=None, fetchprj=None):
        print('start update')
        if fetchshlr is None:
            fetchshlr = self.model.ausgabe('schueler')
        if fetchprj is None:
            fetchprj = self.model.ausgabe('projekte')

        self.view.tableup(fetchshlr, fetchprj)

此调用在 View 准备好之前调用了该函数,因此导致了错误。谢谢您的帮助
我试着不问问题,但经过几个小时的搜索,我不得不问。 我目前正在开发一个程序,最近以 MVC-Scheme 的风格将主文件分成三份。而且我有一个功能可以更新作为表格工作的 Treeview。但是这个功能(而且只有那个!),说:

Exception in Tkinter callback\
Traceback (most recent call last):\
  File "C:\Users\...\Python38\lib\tkinter\__init__.py", line 1883, in __call__\
    return self.func(*args)\
  File "C:/Users/.../Controller.py", line 184, in tabelle_update\
    self.view.table['main'].tag_configure(i[0], background='white')\
AttributeError: 'Controller' object has no attribute 'view'

我已经尝试过使用 lambda(如果你问为什么,因为有人在互联网上说过),它只是阻止了该函数的工作。我也认为这与此有关:

{'model': <Model.Model object at 0x0000018CA8068160>, 'view': <View.View object .>, ...}

这是属性字典的摘录,我认为这与 0x 处的缺失有关...在“模型”中看到的“视图”部分
请帮助我启动并运行它

这是我的重要代码部分(如果您需要更多,请写)
请注意,不同的类位于不同的文件中并且已正确导入

tabelle_update 和 View 类表下 programmcode 的主要变化 我试图将 View 的重部件移到 View 中,但没有解决任何问题。

class Controller(object):
    def __init__(self):
        self.model = Model()
        self.view = View(self.importieren, self.exportieren, self.beenden, self.J5, self.J6, self.J7, self.J8, self.J9,
                         self.J10, self.J11, self.J12, self.tabelle_update, self.tabelle_sorti, self.hinzufugen,
                         self.zuordnen, self.ande, self.tabelle_update, self.model.ausgabe('projekte'),
                         self.tabelle_update, self.a1, self.a2, self.a3, self.a4, self.a5, self.a6, self.a7)
        self.wahlen = ('sErst', 'sZweit', 'sDritt')
        self.delimiter = {'imp_s': None, 'imp_p': None, 'exp': None}
        self.dchosen = None
        self.slcsv = 'schuelerliste.csv'
        self.plcsv = 'projektliste.csv'
        self.double = False
        self.andernx = ""

        self.tabelle()
        self.view.table['main'].bind('<Double-Button-1>', self.treevent)
        # Erstimportierung
        if self.model.ausgabe('schueler'):
            self.importieren(True)

        print(self.__dict__)

        self.view.mainloop()
    
    def tabelle(self):
        fetch = self.model.ausgabe('schueler')
        self.view.shlr_tabelle(fetch)

    def tabelle_update(self, fetchshlr=None, fetchprj=None):
        print('start update')
        if fetchshlr is None:
            fetchshlr = self.model.ausgabe('schueler')
        if fetchprj is None:
            fetchprj = self.model.ausgabe('projekte')

        self.view.tableup(fetchshlr, fetchprj)

class View(ttkthemes.ThemedTk):
    def __init__(self, imp, exp, bee, j5, j6, j7, j8, j9, j10, j11, j12, ja, tabsort, hin, zord, ande, scht,
                 prjt, aktutable, a1, a2, a3, a4, a5, a6, a7):
        # print(ttkthemes.THEMES)   # zum Ausgeben der verfügbaren Themes
        ttkthemes.ThemedTk.__init__(self, theme='breeze')
        self.title("Projektwochenverwaltungsprogramm")
        self.geometry('800x300')
        self.minsize(800, 300)
        self.resizable(width=True, height=True)

        # bestimmen der Callbacks
        self.callback_imp = imp
        self.callback_exp = exp
        self.callback_bee = bee
        self.radiocom = {'jahrg': [j5, j6, j7, j8, j9, j10, j11, j12, ja], 'ande': [a1, a2, a3, a4, a5, a6, a7]}
        self.tabelle_sorti = tabsort
        self.callback_aktut = aktutable
        self.callback_zord = zord
        self.callback_hin = hin
        self.callback_ande = ande
        self.callback_scht = scht
        self.callback_prjt = prjt


        # Tabelle
        self.scrollbars = {'main': Scrollbar(self.rahmen[2], orient="vertical")}
        self.table = {'main': Treeview(self.rahmen[2], yscrollcommand=self.scrollbars['main'].set, height=200)}
        self.scrollbars['main'].pack(side=RIGHT, fill=BOTH)

        self.rahmen[1].pack()
        self.rahmen['popup_pro'].pack(fill=X)
        self.rahmen[2].pack(fill=BOTH, expand=True)


    def shlr_tabelle(self, fetch):
        ml = ['ID']
        for name in self.names['schueler']:
            ml.append(name)
        ml.append('Zugeordned zu')
        self.table['main']['columns'] = ml
        self.table['main']['show'] = 'headings'
        for i in range(len(ml)):
            self.table['main'].column(ml[i], width=self.width['schueler'][i], minwidth=self.width['schueler'][i])
        for i in range(len(ml)):
            self.table['main'].heading(ml[i], text=ml[i], command=lambda col=i: self.tabelle_sorti(col, False, 'main'))
        for t in fetch:
            self.table['main'].insert('', t[0], t[0], values=t)  # , tags=t[0]
        self.scrollbars['main'].config(command=self.table['main'].yview)
        self.table['main'].pack(fill=BOTH)

    def prj_tabelle(self, fetch):
        self.top['prjt'] = Toplevel()
        self.top['prjt'].title('Projekte Liste')
        self.top['prjt'].geometry('800x300')
        self.top['prjt'].minsize(800, 300)
        self.scrollbars['prj'] = Scrollbar(self.top['prjt'], orient="vertical")
        self.table['prj'] = Treeview(self.top['prjt'], yscrollcommand=self.scrollbars['prj'].set, height=200)

        ml = ['ID']
        for name in self.names['projekte']:
            ml.append(name)
        self.table['prj']['columns'] = ml
        self.table['prj']['show'] = 'headings'
        for i in range(len(ml)):
            self.table['prj'].column(ml[i], width=self.width['projekte'][i], minwidth=self.width['projekte'][i])
        for i in range(len(ml)):
            self.table['prj'].heading(ml[i], text=ml[i], command=lambda col=i: self.tabelle_sorti(col, False, 'prj'))
        for t in fetch:
            self.table['prj'].insert('', t[0], t[0], values=t)  # , tags=t[0]
        self.scrollbars['prj'].config(command=self.table['prj'].yview)
        self.scrollbars['prj'].pack(side=RIGHT, fill=BOTH)
        self.table['prj'].pack(fill=BOTH)

    def tableup(self, fetchshlr, fetchprj):
        print('läuft')
        for i in fetchshlr:
            self.view.table['main'].tag_configure(i[0], background='white')
        self.view.table['main'].delete(*self.view.table['main'].get_children())

        for t in fetchshlr:
            self.view.table['main'].insert('', t[0], t[0], values=t)  # , tags=t[0]

        for ele in fetchshlr:
            if ele[8] is None:
                self.view.table['main'].tag_configure(ele[0], background='#fa6150')

        try:
            for i in fetchprj:
                self.view.table['prj'].tag_configure(i[0], background='white')
            self.view.table['prj'].delete(*self.view.table['prj'].get_children())

            for t in fetchprj:
                self.view.table['prj'].insert('', t[0], t[0], values=t)  # , tags=t[0]

            failed = self.model.prj_aktu()
            for prj in failed:
                self.view.table['prj'].tag_configure(prj, background='#fa6150')
        except KeyError:
            pass

【问题讨论】:

  • 使您的代码更易于理解、调试和维护的一件事是执行self.view = View(controller=self) 之类的操作,然后在视图中使用self.controller 访问控制器(例如:self.controller importierenself.controller.a5 等)。没有理由单独传递每个属性。
  • 感谢您的建议,但这不是我能做的事情,因为我被赋予了像我一样去做的任务。

标签: python-3.x class oop object model-view-controller


【解决方案1】:

您必须问自己何时self.view 完全初始化,以及何时尝试访问self.view。该错误告诉您在定义之前尝试访问它。

您应该能够通过添加这样的打印语句来可视化这一点:

print("before self.view is defined")
self.view = View(...)
print("after self.view is defined")

然后:

print("using self.view...")
self.view.table['main'].tag_configure(i[0], background='white')

【讨论】:

  • 我只是尝试过,虽然我认为在 GUI 甚至存在之前不可能使用 GUI 运行函数,但在没有 GUI 的情况下运行命令的唯一点:(待观察在主线程中,因为评论很短)并得到了那个错误:
  • 对不起,我要收回我刚才说的话,但现在发生了这种情况:start init of View\n start update\n done init\n 似乎它在初始化阶段运行错误,但我不知道,为什么会这样在那里执行。在 init 中执行的唯一其他函数是 importieren(True) 和 tabelle(),但最后没有运行 tabelle_update(),而在另一个函数中,只是一个标记,所以是一个打印语句,它没有显示,所以没有被执行。
猜你喜欢
  • 2020-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 2022-08-14
  • 2013-12-30
  • 2021-10-23
相关资源
最近更新 更多