Окно в окне при помощи разных файлов Python Tkinter
Всем привет, буду очень благодарен за разъяснение, постараюсь отчетливо объяснить суть проблемы, с которой сюда решил обратиться. Имеется текстовый редактор, его я сделал отдельным файлом, вот у меня имеется main файл с пустым окошком и файл notepad, как мне его импортировать, чтобы файл содержался внутри окошка main. Не мало был бы рад, если показали как это окно notepad внутри окна main перемещать в удобное положение.
Ниже приведен пример желаемого (рис.1): 
---------- Рисунок 1
Это мой main:
import tkinter as tk
from tkinter import scrolledtext
win= tk.Tk()
h= 1200
w= 650
photo = tk.PhotoImage (file='Logo.png')
win.iconphoto (False, photo)
win.config (bg='#6e4f5f')
win.title('TimLock Alpha v.0.1')
win.geometry(f"{h}x{w}+1000+350")
win.resizable(False, False)
win.mainloop()
Ниже код текстового редактора:
import tkinter as tk
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog**
def chenge_theme(theme):
text_fild['bg'] = view_colors[theme]['text_bg']
text_fild['fg'] = view_colors[theme]['text_fg']
text_fild['insertbackground'] = view_colors[theme]['cursor']
text_fild['selectbackground'] = view_colors[theme]['select_bg']
def chenge_fonts(fontss):
text_fild['font'] = fonts[fontss]['font']
def notepad_exit():
answer = messagebox.askokcancel('Выход', 'Вы точно хотите выйти?')
if answer:
root.destroy()
def open_file():
file_path = filedialog.askopenfilename(title='Выбор файла', filetypes=(('Текстовые документы (*.txt)', '*.txt'), ('Все файлы', '*.*')))
if file_path:
text_fild.delete('1.0', END)
text_fild.insert('1.0', open(file_path, encoding='utf-8').read())
def save_file():
file_path = filedialog.asksaveasfilename(filetypes=(('Текстовые документы (*.txt)', '*.txt'), ('Все файлы', '*.*')))
f = open(file_path, 'w', encoding='utf-8')
text = text_fild.get('1.0', END)
f.write(text)
f.close()
root = Tk()
root.title('Текстовый редактор')
root.geometry('600x700')
main_menu = Menu(root)
file_menu = Menu(main_menu, tearoff=0)
file_menu.add_command(label='Открыть', command=open_file)
file_menu.add_command(label='Сохранить', command=save_file)
file_menu.add_separator()
file_menu.add_command(label='Закрыть', command=notepad_exit)
root.config(menu=file_menu)
view_menu = Menu(main_menu, tearoff=0)
view_menu_sub = Menu(view_menu, tearoff=0)
font_menu_sub = Menu(view_menu, tearoff=0)
view_menu_sub.add_command(label='Светлая', command=lambda: chenge_theme('light'))
view_menu_sub.add_command(label='Тёмная', command=lambda: chenge_theme('dark'))
view_menu.add_cascade(label='Тема', menu=view_menu_sub)
font_menu_sub.add_command(label='Arial', command=lambda: chenge_fonts('Arial'))
font_menu_sub.add_command(label='Comic Sans MS', command=lambda: chenge_fonts('CSMS'))
font_menu_sub.add_command(label='Times New Roman', command=lambda: chenge_fonts('TNR'))
view_menu.add_cascade(label='Шрифт...', menu=font_menu_sub)
root.config(menu=view_menu)
main_menu.add_cascade(label='Файл', menu=file_menu)
main_menu.add_cascade(label='Вид', menu=view_menu)
root.config(menu=main_menu)
f_text = Frame(root)
f_text.pack(fill=BOTH, expand=1)
view_colors = {
'light': {
'text_bg': 'white', 'text_fg': 'black', 'cursor': '#A5A5A5', 'select_bg': '#FAEEDD'
},
'dark': {
'text_bg': 'black', 'text_fg': 'white', 'cursor': 'brown', 'select_bg': 'gray'
}
}
fonts = {
'Arial': {
'font':'Arial 14 bold'
},
'CSMS': {
'font': ('Comic Sans MS', 14, 'bold')
},
'TNR': {
'font': ('Times New Roman', 14, 'bold')
}
}
text_fild = Text(f_text,
bg='white',
fg='black',
padx=10,
pady=10,
wrap=WORD,
insertbackground='brown',
selectbackground='gray',
spacing3=10,
width=30,
font='Arial 14 bold'
)
text_fild.pack(expand=1, fill=BOTH, side=LEFT)
scroll = Scrollbar(f_text, command=text_fild.yview)
scroll.pack(side=LEFT, fill=Y)
text_fild.config(yscrollcommand=scroll.set)
root.mainloop()
Ответы (1 шт):
В первую очередь стоило бы сначала постараться самому найти ответ. Во вторую описать какие варианты решения проблемы были предприняты.
Перепишите код так, чтобы файл можно было подключить как модуль. Для этого опишите весь код блокнота в классе окна, который будет создаваться только если файл запущен, а не подключен как модуль. Примерно так:
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog
view_colors = {
'light': {
'text_bg': 'white', 'text_fg': 'black', 'cursor': '#A5A5A5', 'select_bg': '#FAEEDD'
},
'dark': {
'text_bg': 'black', 'text_fg': 'white', 'cursor': 'brown', 'select_bg': 'gray'
}
}
fonts = {
'Arial': {
'font':'Arial 14 bold'
},
'CSMS': {
'font': ('Comic Sans MS', 14, 'bold')
},
'TNR': {
'font': ('Times New Roman', 14, 'bold')
}
}
class NotepadWindow(Frame):
def __init__(self, root = None):
super(root)
self.text_field = Text(
self,
bg='white',
fg='black',
padx=10,
pady=10,
wrap=WORD,
insertbackground='brown',
selectbackground='gray',
spacing3=10,
width=30,
font='Arial 14 bold'
)
self.text_field.pack(expand=1, fill=BOTH, side=LEFT)
scroll = Scrollbar(self, command=self.text_field.yview)
scroll.pack(side=LEFT, fill=Y)
self.text_field.config(yscrollcommand=scroll.set)
def change_theme(self, theme):
self.text_field['bg'] = view_colors[theme]['text_bg']
self.text_field['fg'] = view_colors[theme]['text_fg']
self.text_field['insertbackground'] = view_colors[theme]['cursor']
self.text_field['selectbackground'] = view_colors[theme]['select_bg']
def change_fonts(self, fontsIdx):
self.text_field['font'] = fonts[fontsIdx]['font']
def open_file(self):
file_path = filedialog.askopenfilename(title='Выбор файла', filetypes=(('Текстовые документы (*.txt)', '*.txt'), ('Все файлы', '*.*')))
if file_path:
self.text_field.delete('1.0', END)
self.text_field.insert('1.0', open(file_path, encoding='utf-8').read())
def save_file(self):
file_path = filedialog.asksaveasfilename(filetypes=(('Текстовые документы (*.txt)', '*.txt'), ('Все файлы', '*.*')))
with open(file_path, 'w', encoding='utf-8') as f:
text = self.text_field.get('1.0', END)
f.write(text)
def prepare_menu(self, root, onExit = None):
def notepad_exit(): # Создаём функцию по нажатию кнопки выход
answer = messagebox.askokcancel('Выход', 'Вы точно хотите выйти?')
if answer and onExit:
onExit()
main_menu = Menu(root)
file_menu = Menu(main_menu, tearoff=0)
file_menu.add_command(label='Открыть', command=self.open_file)
file_menu.add_command(label='Сохранить', command=self.save_file)
file_menu.add_separator()
file_menu.add_command(label='Закрыть', command=notepad_exit)
main_menu.add_cascade(label='Файл', menu=file_menu)
view_menu = Menu(main_menu, tearoff=0)
view_menu_sub = Menu(view_menu, tearoff=0)
font_menu_sub = Menu(view_menu, tearoff=0)
view_menu_sub.add_command(label='Светлая', command=lambda: self.change_theme('light'))
view_menu_sub.add_command(label='Тёмная', command=lambda: self.change_theme('dark'))
view_menu.add_cascade(label='Тема', menu=view_menu_sub)
main_menu.add_cascade(label='Вид', menu=view_menu)
font_menu_sub.add_command(label='Arial', command=lambda: self.change_fonts('Arial'))
font_menu_sub.add_command(label='Comic Sans MS', command=lambda: self.change_fonts('CSMS'))
font_menu_sub.add_command(label='Times New Roman', command=lambda: self.change_fonts('TNR'))
view_menu.add_cascade(label='Шрифт...', menu=font_menu_sub)
return main_menu
if __name__ == '__main__':
root = Tk()
root.title('Текстовый редактор')
root.geometry('600x700')
notepad = NotepadWindow(root)
notepad.pack(fill=BOTH, expand=1)
menu = notepad.prepare_menu(root, lambda: root.destroy())
root.config(menu=menu)
root.mainloop()
После этого класс можно получить в другом файле и подключить его как обычный Frame.
from tkinter import *
from .notepad import NotepadWindow
win = Tk()
h = 1200
w = 650
photo = PhotoImage (file='Logo.png')
win.iconphoto (False, photo)
win.config (bg='#6e4f5f')
win.title('TimLock Alpha v.0.1')
win.geometry(f"{h}x{w}+1000+350")
win.resizable(False, False)
notepad = NotepadWindow(win) # Создаём экземпляр блокнота с родителем win
notepad.pack(fill=BOTH, expand=1) # Размещаем его как обычный Frame
menu = notepad.prepare_menu(win, lamda: win.destroy()) # Получаем меню блокнота с родителем win и его уничтожением по нажатию кнопки "Выход" в меню
win.config(menu=menu) # И прикрепляем как меню окна (либо можно добавить в другое меню)
win.mainloop()