Мне известно о hasattr()
, но я не думаю, что это подойдет для моих конкретных потребностей.Вот ситуация.
В настоящее время у меня есть возможность проверить каталог для классов с определенным типом.IE class TabFrame(ttk.Frame)
будет загружен, поскольку он наследуется именно от ttk.Frame
.
. Я бы предпочел проверить, не содержит ли какой-либо из классов в каталоге атрибут класса, так что я могу более конкретно указать, какой классзагружается.
Основная проблема заключается в том, что у меня нет возможности узнать все имена классов в файлах в каталоге.Мое текущее решение создает кнопки для каждого файла в каталоге, а не для конкретного класса, который я хочу загрузить.
Мой файл, который создает все кнопки на основе имен файлов в каталоге, которые соответствуют моим критериям для допустимых имен файлов.
Итак, проблема в том, что вместо кнопок, которые создаются для каждого допустимого имени файла, мне действительно нужно создать кнопки для каждого допустимого класса в каждом допустимом имени файла.Я подумал, что мог бы использовать простой атрибут класса, такой как self.valid_class = True
, в качестве контроля для того, что загружается в виде кнопки, однако я не знаю, как я могу проверить каждый класс, не импортировав их сначала напрямую.
Пример кода, который вы можетеиспользуйте, чтобы проверить, как это работает:
import tkinter as tk
import tkinter.ttk as ttk
import os
import glob
import importlib.util as iu
from os.path import dirname, basename, isfile, join
file_list = os.listdir('./ScriptFrames')
modules = glob.glob(join(dirname('.\ScriptFrames\\'), "*.py"))
__all__ = [basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
class ScriptManager(tk.Tk):
def __init__(self):
super().__init__()
self.columnconfigure(0, weight=1)
self.tab_list = {}
top_frame = tk.Frame(self)
bot_frame = tk.Frame(self)
self.book = ttk.Notebook(bot_frame)
self.book.pack()
top_frame.pack()
bot_frame.pack()
for ndex, file_name in enumerate([x.split('.')[0] for x in file_list]):
if not any(substring in file_name for substring in ['__', 'TaskFrame']):
tk.Button(top_frame, text=file_name, width=30,
command=lambda fn=file_name: self.add_tab(fn)).grid(row=ndex, column=0, padx=5, pady=1)
def add_tab(self, file_name):
self.process_import(file_name)
self.add_frame_to_book(self.tab_list[file_name])
def add_frame_to_book(self, frame_object):
self.book.add(frame_object, text=frame_object.tab_title)
def process_import(self, fname=None):
if fname is not None:
for fn in __all__:
if fn == fname:
spec = iu.spec_from_file_location('ScriptFrames.{}'.format(fn), '.\ScriptFrames\\{}.py'.format(fn))
modlst = iu.module_from_spec(spec)
spec.loader.exec_module(modlst)
mod_itms = [getattr(modlst, item, None) for item in dir(modlst)]
fc = [item for item in mod_itms if isinstance(item, (type,))
and issubclass(item, (ttk.Frame, tk.LabelFrame))]
self.tab_list[fn] = fc[0]()
if __name__ == '__main__':
ScriptManager().mainloop()
Базовый класс кадров tkinter, используемый из отдельного файла.находится в папке в главном каталоге с именем ScriptFrames.Имя файла TestFrame3
, поэтому кнопка имеет такое имя.
import tkinter as tk
import tkinter.ttk as ttk
class TabFrame(ttk.Frame):
def __init__(self):
super().__init__()
self.valid_tab = "Tab Name" # I want to ID this variable.
self.tab_title = 'Test Frame 3'
tk.Label(self, text=self.tab_title).grid(row=0, column=0, sticky='nsew')
Как файлы загружаются как кнопки, а затем как они загружаются в блокнот tkinter.

Таким образом, все работает так, как задумано, однако я хочу на самом деле проверить каждый класс в файле и посмотреть, есть ли в этом классе переменная, которая сообщитмне, если я должен сделать кнопку, чтобы открыть этот класс в новой вкладке на ноутбуке.
Имейте в виду, я не знаю, сколько файлов или классов находится в этом каталоге, но я хочу сделать кнопку для каждогодопустимый класс в качестве идентификатора в зависимости от того, имеет ли он атрибут класса self.valid_tab
.