如何在Sub类的Parent类中创建Tkinter Widgets

时间:2017-11-17 23:13:21

标签: python python-3.x tkinter

第一个例子在他的父母中创建了帖子标题(除了它在我搜索新标题时不删除旧标题),但是因为它看起来非常混乱我想把类分成2。  其中一个是checkbutton,它用第二个框架扩展第一个框架,并且应该在其中创建post.titles labels。在第二帧(扩展1.frame) 是2个标签,描述了输入字段,2个条目和搜索按钮。此按钮调用StackoverflowApi中的advanced_search函数,并返回post个对象的列表。这是我的第一堂课createPosts函数中需要的列表。

问题在我的第二个例子中,帖子在第二帧中创建而不是在第一帧中。 Here是一个示例,它应该如何看待它现在看起来如何

import tkinter as tk
import tkinter.ttk as ttk
import StackoverflowApi as API

class SearchFrame:
    def __init__(self, parent, title, main_frame):
        self.main_frame=main_frame
        self.title=title
        self.parent=parent
        self.expanded = tk.IntVar()
        self.expanded.set(0)
        self.pagesize=tk.IntVar()
        self.pagesize.set(10)
        self.tags=tk.StringVar()

        self.title_frame=ttk.Frame(self.parent)
        self.title_frame.pack(fill="x", expand=1)

        self.expand_button=ttk.Checkbutton(self.title_frame,
                                           text=self.title +' +',
                                           command=self.expand,
                                           variable=self.expanded,
                                           style='Toolbutton',
                                           )
        self.expand_button.pack(fill='x', expand=1)
        #self.expand_button.configure(bg='grey') gonna fix this later

        self.sub_frame=ttk.Frame(self.parent, relief='sunken', borderwidth=1)

        self.tag_label=ttk.Label(self.sub_frame,
                                 text='Tags').pack(side='left',
                                                   expand=1,
                                                   pady=5)
        self.tag_entry=ttk.Entry(self.sub_frame,
                                 textvariable=self.tags).pack(side='left',
                                                              expand=1,
                                                              pady=5)
        self.pagesize_label=ttk.Label(self.sub_frame,
                                      text='Pagesize').pack(side='left',
                                                            expand=1,
                                                            pady=5)
        self.pagesize_entry=ttk.Entry(self.sub_frame,
                                      textvariable=self.pagesize).pack(side='left',
                                                                       expand=1,
                                                                       pady=5)
        self.search_button=ttk.Button(self.sub_frame, text='Search',
                                      command=self.search).pack(side='left',
                                                                expand=1,
                                                                pady=5)

    def search(self):
        api = API.StackoverflowApi()
        self.posts = api.advanced_search(tagged=list(self.tags.get()),
                                    pagesize=self.pagesize.get())

        for post in self.posts:
            self.post=ttk.Label(self.parent, text=post.title).pack()

    def expand(self):
        if bool(self.expanded.get()):
            self.sub_frame.pack(fill="x", expand=1)
            self.expand_button.configure(text=self.title +' -')
        else:
            self.sub_frame.forget()
            self.expand_button.configure(text=self.title +' +')

root = tk.Tk()
search = SearchFrame(root,'Search Options')
search.search()
root.mainloop()

这是我尝试将上面的代码拆分为两个类,因为我觉得它看起来很混乱

from tkinter import *
from tkinter import ttk
import StackoverflowApi as API

root=Tk()
class FrameOne(ttk.Frame):
    ''' Main Frame in which posts should be created '''
    def __init__(self, parent, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        self.pack()

        #Vars
        self.expanded=IntVar()
        self.expanded.set(0)

        self.expand_button=ttk.Checkbutton(self,
                                           text='Seach Options +',
                                           command=self.expand,
                                           variable=self.expanded,
                                           style='Toolbutton',
                                           )
        self.expand_button.pack(fill='x', expand=1)

        self.sub_frame=ExtendingFrame(parent, relief='sunken', borderwidth=1)


    def expand(self):#function for expanding the second frame
        if bool(self.expanded.get()):
            self.sub_frame.pack(fill="x", expand=1)
            self.expand_button.configure(text='Seach Options -')
        else:
            self.sub_frame.forget()
            self.expand_button.configure(text='Seach Options +')

    def createPosts(self, posts):

        for post in posts:
            self.post=ttk.Label(self, text=post.title)
            self.post.pack()


class ExtendingFrame(FrameOne):
    ''' this is the frame, which apperas when the checkbutton in the first frame
    is clicked.
    The Frame has 2 entries "tags" and "pagesize" I need these for my api call
     '''
    def __init__(self, parent, *args, **kwargs):
        self.parent=parent
        ttk.Frame.__init__(self, parent, *args, **kwargs)

        #Vars
        self.tags=StringVar()
        self.pagesize=IntVar()
        self.pagesize.set(15)

        self.tag_label=ttk.Label(self, text='Tags', anchor='e')
        self.tag_label.pack(fill='x', expand=1, side='left', pady=5, padx=2)
        self.tag_entry=ttk.Entry(self, textvariable=self.tags)
        self.tag_entry.pack(fill='x', expand=1, side='left', pady=5)
        self.pagesize_label=ttk.Label(self, text='Pagesize', anchor='e')
        self.pagesize_label.pack(fill='x', expand=1,side='left', pady=5, padx=2)
        self.pagesize_entry=ttk.Entry(self, textvariable=self.pagesize)
        self.pagesize_entry.pack(fill='x', expand=1, side='left', pady=5)
        self.search_button=ttk.Button(self, text='Search',command=self.search)
        self.search_button.pack(fill='x', expand=1, side='left', pady=5, padx=2)

    def search(self):
        ''' calls the search function of the api, with the '''
        api = API.StackoverflowApi()
        self.posts = api.advanced_search(
                tagged=list(self.tags.get()),
                pagesize=self.pagesize.get()
                 )
        #self.posts is a list of question objects returned by the api
        return super().createPosts(self.posts)#I need the objects from the list in my createPosts function

main=FrameOne(root)
root.mainloop()

1 个答案:

答案 0 :(得分:0)

下面的代码有两个类,MainApp用于构建应用程序的最外层框架,然后是SearchFrame类,它使用MainApp中的方法在其父窗口小部件中创建标签。在这种情况下,SearchFrame的父窗口小部件为MainApp。如果要查看标签实际上是在父窗口小部件子类self.frame2内创建的,则可以将几何管理器注释掉MainApp。我再次怀疑这是一个好习惯:

import tkinter as tk

root = tk.Tk()

class MainApp(tk.Frame):
    def __init__(self, master):
        super().__init__(master)

        #a child frame of MainApp object
        self.frame1 = tk.Frame(self)

        tk.Label(self.frame1, text="This is MainApp frame1").pack()

        self.frame1.grid(row=0, column=0, sticky="nsew")


        #another child frame of MainApp object
        self.frame2 = SearchFrame(self)

        self.frame2.grid(row=0, column=1, sticky="nsew")




    def create_labels(self, master):
        return tk.Label(master, text="asd")


class SearchFrame(tk.Frame):
    def __init__(self, master):
        super().__init__(master)

        self.label = tk.Label(self, text="this is SearchFrame")
        self.label.pack()

        master.label1 = MainApp.create_labels(self, master)

        master.label1.grid()


mainAppObject = MainApp(root)
mainAppObject.pack()

root.mainloop()