Проверка в функциях переменных из класса Python Tkinter
Я делаю текстовой редактор на Tkinter, в котором делаю функции для работы с файлами.
У меня есть класс с переменными, в которые заносятся файлы через askopenfilename() во время работы определенных функций.
Но в моем коде не корректно работают операторы сравнения значения переменных, которые находятся в классе. Когда в одной функции файл записывается в переменную из класса, его значение не получается проверить в другой функции:
# This Python file uses the following encoding: utf-8
from tkinter import *
import tkinter.messagebox as tkMessageBox
from tkinter.filedialog import *
import os
# VARIABLES
class class_file:
file_open = None
file = None
# FUNCTIONS
def save_file_as(class_file, *args):
class_file.file_open = askopenfilename(defaultextension=".txt", filetypes=[("All Files", "*.*")])
class_file.file = open(class_file.file, "w")
class_file.file.write(Textedit.get(1.0, END))
class_file.file.close()
window.title(os.path.basename(class_file.file) + " - Editor")
return class_file.file_open and class_file.file
def open_file(*args):
class_file.file_open = askopenfilename(defaultextension=".txt", filetypes=[("All Files", "*.*")])
if class_file.file_open is not None and class_file.file_open != '':
window.title(os.path.basename(class_file.file_open) + " - Editor")
Textedit.delete(1.0, END)
class_file.file = open(class_file.file_open, "r")
Textedit.insert(1.0, class_file.file.read())
class_file.file.close()
return class_file.file_open and class_file.file
def new_file(*args):
window.title("Untitled - PySider Editor")
Textedit.delete(1.0, END)
class_file.file_open = None
class_file.file = None
return class_file.file_open and class_file.file
def save_file(*args):
if class_file.file_open and class_file.file == None:
save_file_as()
elif class_file.file_open and class_file.file != None:
class_file.file = open(class_file.file_open, "w")
class_file.file.write(Textedit.get(1.0, END))
class_file.file.close()
return class_file.file_open and class_file.file
else:
print("error")
def close_file(*args):
window.title("Editor")
Textedit.delete(1.0, END)
class_file.file_open = None
class_file.file = None
return class_file.file_open and class_file.file
# MAIN
window = Tk()
# Window
window.title("Editor")
window.geometry('1250x680')
window["bg"] = "#333"
# Top menu
menu = Menu(window)
# File
file_items = Menu(menu)
file_items.add_command(label='New File Ctrl+N', command=new_file)
file_items.add_command(label='Open File Ctrl+O', command=open_file)
file_items.add_command(label='Close File Ctrl+W', command=close_file)
file_items.add_command(label='Close All ')
file_items.add_command(label='Save Ctrl+S', command=save_file)
file_items.add_command(label='Save All ')
menu.add_cascade(label='File', menu=file_items)
window.config(menu=menu)
# Text
Textframe = Frame(window)
Textframe.pack(fill=BOTH, expand=True)
Textedit = Text(Textframe, bg="#333", fg="white", font=('Arial', 14), insertbackground="white", insertwidth=3, wrap=WORD)
Textedit.pack(fill=BOTH, expand=True)
window.mainloop()
Здесь когда переменные file_open и file равны None, это не получается проверить, будто они равны чему то другому. Из-за этого при выполнении функции save_file ничего не происходит.
В функции save_file я добавил оператор else, при его выполнении выводится "error". Когда else выполнился, я подумал, что условия предыдущих операторов не соответствует, и добавил return. Но от этого ничего не изменилось.
Помогите мне понять в чем тут дело.
Ответы (2 шт):
Основная проблема в том, что вам надо работать с экземпляром класса.
Я вам предложу:
1 Замените имя класса и создайте его экземпляр
...
#class class_file:
class ClassFile:
file_open = None
file = None
...
class_file = ClassFile()
print(f'func main: {class_file.file_open}, {class_file.file}')
window.mainloop()
2 В функциях, которые вы будете тестировать, вставьте
print(f'func <name_func>: {class_file.file_open}, {class_file.file}')
чтобы вам было понятно, с какими значениями вы оперируете.
3 return class_file.file_open and class_file.file
в ваших функциях не нужны, если вам надо изменить
class_file.file_open или class_file.file -
просто измените его, например, так: class_file.file_open = None
4 подумайте о смысле проверки условий, например зачем
if class_file.file_open is not None and class_file.file_open != '':
если достаточно - if class_file.file_open:
...
Update
Мне нужно написать такие функции, чтобы когда пользователь нажимал на Save в меню, выполнялась функция save_file. И далее если какой либо файл был уже открыт и переменные file_open и file не равны None, файл просто сохранялся. А если эти переменные равны None, например когда редактор запустился, и выполнилась функция save_file появлялось окно asksaveasfilename() - Сохранить как
я не сильно следовал вашим требованиям, но внес некоторые изменения. Проверьте:
from tkinter import *
import tkinter.messagebox as tkMessageBox
from tkinter.filedialog import *
import os
#class class_file:
class ClassFile:
file_open = None
file = None
# FUNCTIONS
#def save_file_as(class_file, *args):
def save_file_as(*args):
class_file.file_open = askopenfilename(defaultextension=".txt", filetypes=[("All Files", "*.*")])
print(f'1 def save_file_as(*args): {class_file.file_open}, {class_file.file}')
# class_file.file = open(class_file.file, "w")
class_file.file = open(class_file.file_open, "w") # + file_open
class_file.file.write(Textedit.get(1.0, END))
class_file.file.close()
# window.title(os.path.basename(class_file.file) + " - Editor")
window.title(os.path.basename(class_file.file_open) + " - Editor")
#? return class_file.file_open and class_file.file
def open_file(*args):
class_file.file_open = askopenfilename(defaultextension=".txt", filetypes=[("All Files", "*.txt*")])
print(f'1 def open_file(*args): {class_file.file_open}, {class_file.file}')
if class_file.file_open is not None and class_file.file_open != '':
window.title(os.path.basename(class_file.file_open) + " - Editor")
Textedit.delete(1.0, END)
class_file.file = open(class_file.file_open, "r")
Textedit.insert(1.0, class_file.file.read())
class_file.file.close()
print(f'2 def open_file(*args): {class_file.file_open}, {class_file.file}')
# ? return class_file.file_open and class_file.file
def new_file(*args):
print(f'1 def new_file(*args): {class_file.file_open}, {class_file.file}')
window.title("Untitled - PySider Editor")
Textedit.delete(1.0, END)
class_file.file_open = None
class_file.file = None
print(f'2 def new_file(*args): {class_file.file_open}, {class_file.file}')
#? return class_file.file_open and class_file.file
def save_file(*args):
print(f'2 def save_file(*args): {class_file.file_open}, {class_file.file}')
# if class_file.file_open and class_file.file == None:
if class_file.file_open is None and class_file.file is None:
save_file_as()
elif class_file.file_open and class_file.file != None:
class_file.file = open(class_file.file_open, "w")
class_file.file.write(Textedit.get(1.0, END))
class_file.file.close()
#? return class_file.file_open and class_file.file
else:
print("error")
def close_file(*args):
window.title("Editor")
Textedit.delete(1.0, END)
class_file.file_open = None
class_file.file = None
return class_file.file_open and class_file.file
# MAIN
window = Tk()
# Window
window.title("Editor")
window.geometry('1250x680')
window["bg"] = "#333"
# Top menu
menu = Menu(window)
# File
file_items = Menu(menu)
file_items.add_command(label='New File Ctrl+N', command=new_file)
file_items.add_command(label='Open File Ctrl+O', command=open_file)
file_items.add_command(label='Close File Ctrl+W', command=close_file)
file_items.add_command(label='Close All ')
file_items.add_command(label='Save Ctrl+S', command=save_file)
file_items.add_command(label='Save All ')
menu.add_cascade(label='File', menu=file_items)
window.config(menu=menu)
# Text
Textframe = Frame(window)
Textframe.pack(fill=BOTH, expand=True)
Textedit = Text(Textframe, bg="#333", fg="white", font=('Arial', 14), insertbackground="white", insertwidth=3, wrap=WORD)
Textedit.pack(fill=BOTH, expand=True)
class_file = ClassFile()
print(f'func main: {class_file.file_open}, {class_file.file}')
window.mainloop()
Здесь когда переменные
file_openиfileравныNone, это не получается проверить
В этом условии class_file.file_open and class_file.file == None у вас проверяется не то, что оба поля равны None, а то что первое поле истинно, а второе равно None.
Нужно записать так: class_file.file_open is None and class_file.file is None. Или проверять что что оба поля ложны (например, в них None или пустые строки): not class_file.file_open and not class_file.file.
Про истинность или ложность значений см. например тут в разделе "Проверка истинности": Инструкция if-elif-else, проверка истинности, трехместное выражение if/else