我正在尝试创建一个简单的开源项目,用可听日本的元数据标记日本有声读物。我有一个可以抓取标题、作者和叙述者的工作脚本,我正在尝试用这些数据填充Tkinter的树。当我尝试使用OOP方法时,问题就出现了,并将所有的东西分解成不同的类和函数。
import tkinter as tk
from tkinter import *
from tkinter import ttk
import requests
from bs4 import BeautifulSoup
class ResultFrame(ttk.Frame):
def __init__(self, container):
super().__init__(container)
# field options
options = {'padx': 10, 'pady': 10}
# result label frame
self.result_label = ttk.LabelFrame(self, text='Results')
self.result_label.grid(row=1, column=0, sticky=tk.W, **options)
# result tree
self.tree = ttk.Treeview(self.result_label)
self.tree['columns'] = ("Title", "Author", "Narrator", "Published")
self.tree.column("#0", width=0, stretch=NO) # hide the first autogenerated column
self.tree.column("Title", anchor=W)
self.tree.column("Author", anchor=W)
self.tree.column("Narrator", anchor=W)
self.tree.column("Published", anchor=W)
# result tree headings
self.tree.heading('#0', text='') # hide the first autogenerated column
self.tree.heading('Title', text='Title', anchor=W)
self.tree.heading('Author', text='Author', anchor=W)
self.tree.heading('Narrator', text='Narrator', anchor=W)
self.tree.heading('Published', text='Published', anchor=W)
self.tree.pack()
self.grid(padx=10, pady=10, sticky=tk.NSEW)
def populate_tree(self, data):
count = 0
for book in data.items():
self.tree.insert(
parent='', index='end', iid=count, text='',
values=(
book[0], book[1]['authors'], book[1]['narrators'], 'not implemented'
)
)
count += 1
class SearchFrame(ttk.Frame):
def __init__(self, container):
super().__init__(container)
self.audiobooks = {}
# field options
options = {'padx': 5, 'pady': 5}
# search label
self.search_label = ttk.Label(self, text='Search')
self.search_label.grid(row=0, column=0, sticky=tk.W, **options)
# search entry
self.search = tk.StringVar()
self.search_entry = ttk.Entry(self, textvariable=self.search, width=50)
self.search_entry.grid(row=0, column=1, **options)
self.search_entry.focus()
self.search_button = ttk.Button(self, text="search")
self.search_button['command'] = self.search_audible
self.search_button.grid(row=0, column=2, sticky=tk.W, **options)
# # results label
# self.result_label = ttk.Label(self)
# self.result_label.grid(row=1, columnspan=3, **options)
# add padding to the frame and show it
self.grid(padx=10, pady=10, sticky=tk.NSEW)
def search_audible(self):
"""
Search audible for the book
:param self:
:return:
"""
temp_authors = []
temp_narrators = []
# build the url
base_url = "https://www.audible.co.jp/search?ipRedirectOverride=true&overrideBaseCountry=true&keywords="
query = self.search_entry.get()
# request the page
page = requests.get(base_url + query)
soup = BeautifulSoup(page.content, "html.parser")
# grab only the content that we need
search_results = soup.find(id="center-3")
# scrape information
for product_item in search_results.find_all('li', class_="bc-list-item productListItem"):
title = product_item['aria-label']
# get all of the authors from anchor tags
for link in soup.find("li", class_="bc-list-item authorLabel").find_all("a"):
if link.text not in temp_authors:
temp_authors.append(link.text)
# join the results with comma separation to prepare for MP3/M4B file tags
authors = ", ".join(temp_authors)
for link in soup.find("li", class_="bc-list-item narratorLabel").find_all("a"):
if link.text not in temp_narrators:
temp_narrators.append(link.text)
narrators = ", ".join(temp_narrators)
self.audiobooks[title] = {
"authors": authors,
"narrators": narrators
}
ResultFrame.populate_tree(self, data=self.audiobooks)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title('Audiobook Tagger')
if __name__ == '__main__':
app = App()
SearchFrame(app)
ResultFrame(app)
app.mainloop()根据我的理解,读到这个答案:https://stackoverflow.com/a/41513358,本质上我必须让ResultFrame继承SearchFrame,所以它将是ResultFrame(SearchFrame)而不是ResultFrame(ttk.Frame)。但问题是,我的两个类都是从ttk.Frame继承的,所以我不确定如何继续。
为了总结我的问题,在我的SearchFrame search_audible 类中,名为search_audible的函数从声音中收集信息。我想把这些被刮掉的信息发送给ResultFrame__'s populate_tree() ,这样它就可以方便地显示结果。
如果可能的话,我更希望将这两个框架分成独立的类,因为在我看来,它有助于组织和管理代码。
发布于 2021-10-09 05:49:51
总结我的问题,在我的SearchFrame类中,名为search_audible的函数从声音中收集信息。我想将被刮掉的信息发送到ResultFrame的populate_tree(),以便它能够方便地显示结果。
为了做到这一点,SearchFrame需要了解ResultFrame。你可以这样做:
class SearchFrame(ttk.Frame):
def __init__(self, container,reciever):
super().__init__(container)
self.reciever = reciever通过该引用,您可以通过以下方法锁定该对象:
self.reciever.populate_tree(self, data=self.audiobooks)由于您需要对该对象的引用,所以需要交换构造的顺序,以获得可以传递的引用:
res = ResultFrame(app)
ser = SearchFrame(app,res)提示
class App(tk.Tk):
def __init__(self):
super().__init__()
self.res = ResultFrame(self)
self.ser = SearchFrame(self,self.res)
self.title('Audiobook Tagger')
if __name__ == '__main__':
app = App()
app.mainloop()https://stackoverflow.com/questions/69504055
复制相似问题