@Fizl

Как взаимодействовать с переменной функции в другой функции в одном классе?

Надеюсь, что корректно задал вопрос )
Есть переменная "self.text_show", она находиться в классе MAIN_WIND функции init_main. Я пытаюсь взаимодействовать с этой переменной в функции follow_2, но почему-то все равно выдает ошибку, хотя я могу провернуть такое же с переменной text_enteremail и функцией follow. Помогите это исправить(здесь только часть кода, поэтому некоторых классов, с которыми идет взаимодействие, нет)
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import codecs
import email
import imaplib
from threading import Thread
import threading
from tkinter import messagebox
from email.header import decode_header
import codecs
import time
import os

class MAIN_WIND(tk.Frame):
    def __init__(self, main_root):
        super().__init__(main_root)
        self.contact_name = "TXT"
        self.MAIL = MAIL('ПОЧТА', smtplib.SMTP('smtp.gmail.com:587'))
        self.GET_MAIL = GET_MAIL(imaplib.IMAP4_SSL('imap.gmail.com'))
        threading.Thread(target = self.GET_MAIL.get_mail_func, daemon=True).start()
        threading.Thread(target = self.follow_2, daemon = True).start()
        self.init_main()

    def follow(self, name):
        current = codecs.open(name, "r", encoding = "utf-8")
        curino = os.fstat(current.fileno()).st_ino
        while True:
            while True:
                line = current.readline()
                if not line:
                    break
                yield line

            try:
                if os.stat(name).st_ino != curino:
                    new = open(name, "r")
                    current.close()
                    current = new
                    curino = os.fstat(current.fileno()).st_ino
                    continue
            except IOError:
                pass
            time.sleep(1)

    def follow_2(self):
        if __name__ == '__main__':
            for l in self.follow(f"{self.contact_name}.txt"):
                #print(format(l))
                self.text_show.insert(1.0, l)


    def retrieve_mail(self):
        self.retr_mail = self.text_enteremail.get(1.0, tk.END)
        self.MAIL.send_mail(self.retr_mail)

    def init_main(self):
        self.MAIL.start_client('smtp.gmail.com:587')

        self.btn_dialog_sendmail = tk.Button(main_root, text = '➤', padx = 8, pady = 24, font = ('Ubuntu',25), command = self.retrieve_mail)
        self.text_enteremail = tk.Text(main_root, width = 30, height = 6, bg='white', fg='black', font = ('COMIC SANS MS',10))

        #////SCROLLBAR////
        self.dialog_frame = tk.Frame(main_root)
        #///////////////Вот эта переменная/////////////////
        self.text_show = tk.Text(self.dialog_frame,width=40, height=24)
        #//////////////////////////////////////////////////
        self.scroll = tk.Scrollbar(self.dialog_frame, command=self.text_show.yview)
        self.scroll.pack(side=tk.RIGHT, fill=tk.Y)
        self.text_show.config(yscrollcommand=self.scroll.set)
        self.text_show.configure(state='disabled')
        self.text_show.pack(side=tk.TOP) 
        self.dialog_frame.pack(side=tk.TOP)
        #////END SCROLLBAR////

        self.btn_dialog_sendmail.pack()
        self.text_enteremail.pack()

        self.btn_dialog_sendmail.place(x = 279,y = 400)
        self.text_enteremail.place(x = 29, y = 400)
  • Вопрос задан
  • 90 просмотров
Решения вопроса 2
@twistfire92
Python backend developer
Попробуйте эту строку
self.text_show = tk.Text(self.dialog_frame,width=40, height=24)

Перенести в функцию __init__()

У вас follow_2 вызывается раньше, чем вызывается init_main() а text_show определяется только в ней.
можно просто init_main() перенести выше на 2 строки.
Ответ написан
@Fizl Автор вопроса
Итак, спасибо за помощь всем !
Вот что вышло :
import tkinter as tk
from tkinter import ttk
from functools import partial
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import codecs
import email
import imaplib
from threading import Thread
import threading
from tkinter import messagebox
from email.header import decode_header
import codecs
import time
import os

class MAIN_WIND(tk.Frame):
    def __init__(self, main_root):
        super().__init__(main_root)
        self.contact_name = "TXT"
        self.MAIL = MAIL('youremail@gmail.com', smtplib.SMTP('smtp.gmail.com:587'))
        self.GET_MAIL = GET_MAIL(imaplib.IMAP4_SSL('imap.gmail.com'))
        self.init_main()
        threading.Thread(target = self.main, daemon = True).start()



    def follow(self, name):
        current = codecs.open(name, "r", encoding = "utf-8")
        curino = os.fstat(current.fileno()).st_ino
        while True:
            while True:
                line = current.readline()
                if not line:
                    break
                yield line

            try:
                if os.stat(name).st_ino != curino:
                    new = open(name, "r")
                    current.close()
                    current = new
                    curino = os.fstat(current.fileno()).st_ino
                    continue
            except IOError:
                pass
            time.sleep(1)

    def follow_2(self):
        if __name__ == '__main__':
            for l in self.follow(f"{self.contact_name}.txt"):
                #print(format(l))
                self.text_show.insert(1.0, l)

    def main(self):
        threading.Thread(target = self.follow_2, daemon = True).start()
        threading.Thread(target = self.GET_MAIL.get_mail_func, daemon=True).start()

    def retrieve_mail(self):
        self.retr_mail = self.text_enteremail.get(1.0, tk.END)
        self.MAIL.send_mail(self.retr_mail)

    def init_main(self):
        self.MAIL.start_client('smtp.gmail.com:587')

        self.btn_dialog_sendmail = tk.Button(main_root, text = '➤', padx = 8, pady = 24, font = ('Ubuntu',25), command = self.retrieve_mail)
        self.text_enteremail = tk.Text(main_root, width = 30, height = 6, bg='white', fg='black', font = ('COMIC SANS MS',10))

        #////SCROLLBAR////
        self.dialog_frame = tk.Frame(main_root)
        #///////////////Вот эта переменная/////////////////
        self.text_show = tk.Text(self.dialog_frame,width=40, height=24)
        #/////////////////////////////////////////////////
        self.scroll = tk.Scrollbar(self.dialog_frame, command=self.text_show.yview)
        self.scroll.pack(side=tk.RIGHT, fill=tk.Y)
        self.text_show.config(yscrollcommand=self.scroll.set)
        #self.text_show.configure(state='disabled')
        self.text_show.pack(side=tk.TOP) 
        self.dialog_frame.pack(side=tk.TOP)
        #////END SCROLLBAR////

        self.btn_dialog_sendmail.pack()
        self.text_enteremail.pack()

        self.btn_dialog_sendmail.place(x = 279,y = 400)
        self.text_enteremail.place(x = 29, y = 400)

Нужно было перенести init_main() выше потока и убрать строку "self.text_show.configure(state='disabled')". Еще для удобства (вроде бы необязательно) можно запустить только один поток, внутри которого работают два потока))
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы