tkinter正在采取与给定的不同的大师

时间:2018-07-24 20:24:51

标签: python tkinter

我有一个顶层窗口小部件,它询问用户他想产生什么窗口小部件,然后询问cnf。什么和东西都不重要。

cnf将在Scrollframe-Table-something中被问到(我真的不知道如何描述它^^')。对于该Scrollframe及其滚动条,我制作了一个Frame,因此可以轻松地左右包装它。但是,以某种方式,Scrollframe会将Tk窗口(顶层的根目录)作为主窗口。

这是代码-我找不到我的错误:

from tkinter import _cnfmerge as cnfmerge
from tkinter import *
class Scrollframe(Frame):
    def __init__(self,master=None,height=200,width=200,**kw):
        if 'yscrollcommand' in kw:
            self.ysc=kw['yscrollcommand']
            del kw['yscrollcommand']
        else: ysc=None
        if 'pad' in kw:
            self.pad=kw['pad']
            del kw['pad']
        else: self.pad=0
        Frame.__init__(self,height=height,width=width)
        self.scrollframe=Frame(self,**kw)
        self.scrollframe.place(x=0,y=0,relwidth=1)
        self.config(bg=self.scrollframe['bg'])
        self.bind('<Configure>',self.adopt)
        self.widgets,self.scrollable={},False
    def adopt(self,event=None):
        if self.scrollframe.winfo_height()>self.winfo_height():
            self.scrollable=True
            self.scrollframe.place(y=0)
            self.ysc(0,0)
        else:
            self.scrollable=False
            self.ysc(0,1)
    def addItem(self,widget=None,cnf={},**kw):
        if widget:
            cnf=cnfmerge((cnf,kw))
            if 'width' in cnf: del cnf['width']
            obj=widget(self.scrollframe,cnf)
            if len(self.widgets)==0 and self.pad!=0: obj.pack(fill=X)
            else: obj.pack(fill=X,pady=(self.pad,0))
            id_=str(id(obj))+widget.__name__
            obj.bind('<Destroy>',lambda event: self.delItem(id_),'+')
            self.widgets[id_]=obj
            return id_
    def getItem(self,id):
        return self.widgets[id]
    def delItem(self,id):
        try: self.widgets[id].destroy()
        except TclError: del self.widgets[id]
        except KeyError: pass 
    def yview(self,*args):
        try: delta=int(args[1])
        except ValueError: delta=float(args[1])
        maxnegscroll=self.winfo_height()-self.scrollframe.winfo_height()
        if isinstance(delta,float):
            if maxnegscroll<0: self.scrollframe.place(y=int(maxnegscroll*delta))
            delta=abs(int(self.scrollframe.place_info()['y'])/maxnegscroll)
            self.ysc(delta,delta)
        else:
            delta=-delta*3
            if int(self.scrollframe.place_info()['y'])+delta<maxnegscroll: self.scrollframe.place(y=maxnegscroll)
            elif int(self.scrollframe.place_info()['y'])+delta>0: self.scrollframe.place(y=0)
            else: self.scrollframe.place(y=int(self.scrollframe.place_info()['y'])+delta)
            delta=abs(int(self.scrollframe.place_info()['y'])/maxnegscroll)
            self.ysc(delta,delta)

class CreateWindow(Toplevel):
    def __init__(self,master=None):
        Toplevel.__init__(self,master,height=458,width=400)
        self.grab_set()
        self.resizable(False,False)
        self.title('Neues Item')
        self.vars,self.cnf,self.cnfids={},{},{}

        cnf=create_dict(bg='gainsboro',width=380)
        Frame(self,cnf=cnf,height=39).place(x=10,y=10)
        Frame(self,cnf=cnf,height=103).place(x=10,y=59)
        Frame(self,cnf=cnf,height=220).place(x=10,y=172)
        bottom=Frame(self,cnf=cnf,height=46)
        bottom.pack_propagate(False)
        bottom.place(x=10,y=402)

        var,values,self.oldwidget=StringVar(value='Frame'),list(_tkinter_widgets.keys())[2:],'Frame'
        for i in range(len(values)): values[i]=values[i].__name__
        Spinbox(self,values=values,textvar=var,state=READONLY,cursor='arrow',command=self.refresh,buttonuprelief=FLAT,buttondownrelief=FLAT,wrap=True).place(x=20,y=20)
        self.vars['widget']=var

        Label(self,text='Höhe:',bg='gainsboro',anchor=W,bd=1).place(x=20,y=69)
        var=StringVar()
        Entry(self,textvar=var,justify=CENTER,width=40).place(x=136,y=69)
        self.vars['height']=var
        Label(self,text='Breite:',bg='gainsboro',anchor=W,bd=1).place(x=20,y=98)
        var=StringVar()
        Entry(self,textvar=var,justify=CENTER,width=40).place(x=136,y=98)
        self.vars['width']=var
        var=BooleanVar(value=True)
        Checkbutton(self,onvalue=True,offvalue=False,text='Farbe übernehmen (falls vorhanden)',variable=var,cursor='hand2',bg='gainsboro',activebackground='gainsboro').place(x=20,y=127)
        self.vars['takecolor']=var

        cnfsframe=Frame(self,height=200,width=360)
        cnfsframe.pack_propagate(0)
        cnfsframe.place(x=20,y=182)
        sb=Scrollbar(cnfsframe)
        sb.pack(fill=Y,side=RIGHT)
        self.cnfs=Scrollframe(master=cnfsframe,width=360-17,height=200,yscrollcommand=sb.set)
        self.cnfs.pack(fill=Y,side=LEFT)
        sb.config(command=self.cnfs.yview)
        for arg in _tkinter_widgets[Frame]:
            id=self.cnfs.addItem(Frame,height=19,width=360)
            obj=self.cnfs.getItem(id)
            var=StringVar()
            Entry(obj,width=35,justify=CENTER,textvar=var).place(x=146,y=0)
            Label(obj,text=arg,bd=1).place(x=0,y=0)
            self.cnf[arg],self.cnfids[arg]=var,id

        Button(bottom,text='Bestätigen',command=self.confirm,width=12,height=1).pack(side=LEFT,padx=10,pady=10)
        Button(bottom,text='Abbrechen',command=self.destroy,width=12,height=1).pack(side=RIGHT,padx=(0,10),pady=10)
    def refresh(self):
        self.vars['height'].set(''),self.vars['width'].set(''),self.vars['takecolor'].set(True)
        for arg in _tkinter_widgets[eval(self.oldwidget)]:
            self.cnfs.delItem(self.cnfids[arg])
            del self.cnfids[arg],self.cnf[arg]
        for arg in _tkinter_widgets[eval(self.vars['widget'].get())]:
            id=self.cnfs.addItem(Frame,height=19,width=360)
            obj=self.cnfs.getItem(id)
            obj.pack_propagate(False)
            var=StringVar()
            Entry(obj,width=35,justify=CENTER,textvar=var).pack(side=RIGHT)
            Label(obj,text=arg,bd=1).pack(fill=X,side=LEFT)
            self.cnf[arg],self.cnfids[arg]=var,id
        self.oldwidget=self.vars['widget'].get()
        self.focus()
    def confirm(self):
        raise NotImplementedError #first I'll have to fix that scrollframe issue xD

if __name__=='__main__':
    t=Tk()
    cw=CreateWindow(t)

在有人问Scrollframe中的self.scrollable是干什么的之前:我将在稍后实现的MouseWheel绑定。

1 个答案:

答案 0 :(得分:4)

在这一行中,您没有将主服务器传递给超类'__init__

Frame.__init__(self,height=height,width=width)

只需将其更改为:

Frame.__init__(self,master=master, height=height,width=width)

也就是说,Python的一般建议是使用super()而不是对超类名称进行硬编码:

super().__init__(master=master, height=height, width=width)