Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » вызвать объект из другого объекта [RSS Feed]

#1 Фев. 6, 2014 17:00:10

zlodiak
От: Россия
Зарегистрирован: 2014-01-19
Сообщения: 159
Репутация: +  0  -
Профиль   Адрес электронной почты  

вызвать объект из другого объекта

помогите пожалуйста исправить скрипт.

import tkinter
import tkinter.messagebox
class Operations():
    def new(self, parent):
        global workArea
        if workArea == True:
            tkinter.messagebox.showwarning('Warning', 'New document is already open')
        else:    
            self.new = WorkArea(parent)
            workArea = True      
    
    def openFile(self):
        global workArea
        if workArea == True:
            tkinter.messagebox.showwarning('Warning', 'Close the open document')
        else:
            try:
                nameOpenFile = tkinter.filedialog.askopenfilename(title = 'Open textPad file', filetypes=[("textPad files", "*.tpd")])
            except Exception:
                pass
            else:
                try:
                    pointerFileOpened = open(nameOpenFile, 'rt')
                except Exception:
                    tkinter.messagebox.showerror('Error', 'Open file error')
                else:
                    self.new(root)
                    self.readFile(pointerFileOpened)
                finally:                        
                    pointerFileOpened.close()
    def readFile(self, pointerFileOpened):
        while True:
            line = pointerFileOpened.readline()
            if len(line) == 0:
                break
            else:
                self.new.insert(tkinter.END, line)  #this is problem line
        return
class WorkArea():
    def __init__(self, parent):
        parent.title("My default workarea")
        
        workArea = tkinter.Text(parent)
        workArea.pack(expand = 'yes', fill = 'both')
     
class ToolBar(Operations, tkinter.Frame):
    def __init__(self, parent):
        tkinter.Frame.__init__(self, parent)
        self.parent = parent  
        self.makeToolBar()
        
    def makeToolBar(self):
        frame = tkinter.Frame(self.parent)
        frame.pack(side = 'top', fill = 'x')
        
        tool1 = tkinter.Button(frame, text = 'New', command = lambda: self.new(root))
        tool1.pack(side = 'left')
        tool2 = tkinter.Button(frame, text = 'Open', command = lambda: self.openFile())
        tool2.pack(side = 'left')
workArea = False
root = tkinter.Tk()
root.geometry('900x500+200+100')
toolBar = ToolBar(root)
root.mainloop()

проблема в том, что поле того как пользователь нажимает кнопку “open” и выбирает файл для открытия, не происходит вывод содержимого файла на экран, а происходит вывод следующего сообщения об ошибке:
File “C:\Python33\projects\TEXTPADS\textPad_OOP\q.py”, line 32, in openFile
self.readFile(pointerFileOpened)
File “C:\Python33\projects\TEXTPADS\textPad_OOP\q.py”, line 42, in readFile
self.new.insert(tkinter.END, line) #this is problem line
AttributeError: ‘WorkArea’ object has no attribute ‘insert’

если можно, то помогите пожалуйста переписать класс WorkArea правильным образом.

Офлайн

#2 Фев. 6, 2014 22:43:47

Ryoga
Зарегистрирован: 2014-02-01
Сообщения: 20
Репутация: +  1  -
Профиль   Отправить e-mail  

вызвать объект из другого объекта

Ну, вообще-то ты пытаешься вызвать метод insert() у self.new, который, в зависимости от логики программы, может быть либо методом класса Operations, либо его же аттрибутом, экземпляром класса WorkArea (я от такой иезуитской логики чуть не поседел) В любом случае, твой класс WorkArea не является наследником tkinter.Text, а метод insert() ты ему не определяешь.

Для начала таки надо определиться, где ты вообще будешь хранить экземпляр tkinter.Text - в экземпляре класса WorkArea, или непосредственно в этом классе(что имхо глупо, но всяко лучше, чем в локальной переменной метода __init__)?

Соответственно, класс будет выглядеть как:

class WorkArea():
    def __init__(self, parent):
        parent.title("My default workarea")
        
        self.workArea = tkinter.Text(parent)
        self.workArea.pack(expand = 'yes', fill = 'both')

или, на худой конец, так:

class WorkArea():
    def __init__(self, parent):
        parent.title("My default workarea")
        
        WorkArea.workArea = tkinter.Text(parent)
        WorkArea.workArea.pack(expand = 'yes', fill = 'both')

а злополучную строчку надо переписать в виде:

self.new.workArea.insert(tkinter.END, line) 

По крайней мере, так оно заработает, хотя даже на мой непросвещенный вкус, переписать в приведенном отрывке стоило бы многое.

Офлайн

#3 Фев. 7, 2014 00:14:21

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

вызвать объект из другого объекта

zlodiak
Дам только одну рекомендацию: не пишите пока GUI с использованием классов.
Пройдет время и начнет все нормально получаться. Тогда и перепишите.

Ryoga Вы указали правильное решения, но потом от него ушли почему-то. Нужно сразу наследовать от tkinter.Text. Зачем делать единственный виджет еще и единственным атрибутом класса.
Также согласен относительно “переписать”. Класс из одного виджета выглядит жутко. Просто МЕГАжутко.
А этот код - это вообще абзец…

def __init__(self, parent):
        tkinter.Frame.__init__(self, parent)
        self.parent = parent  
        self.makeToolBar()
        
def makeToolBar(self):
        frame = tkinter.Frame(self.parent)
        frame.pack(side = 'top', fill = 'x')

+ за global бил бы по рукам…

Отредактировано 4kpt_II (Фев. 7, 2014 00:37:03)

Офлайн

#4 Фев. 7, 2014 09:04:12

zlodiak
От: Россия
Зарегистрирован: 2014-01-19
Сообщения: 159
Репутация: +  0  -
Профиль   Адрес электронной почты  

вызвать объект из другого объекта

ну спасибо. я можно сказать прозрел(относительно) после ваших ценных замечаний. очень много полезного понял

Отредактировано zlodiak (Фев. 7, 2014 09:14:04)

Офлайн

#5 Фев. 7, 2014 10:43:08

Ryoga
Зарегистрирован: 2014-02-01
Сообщения: 20
Репутация: +  1  -
Профиль   Отправить e-mail  

вызвать объект из другого объекта

4kpt_II
Ryoga Вы указали правильное решения, но потом от него ушли почему-то. Нужно сразу наследовать от . Зачем делать единственный виджет еще и единственным атрибутом класса.
Также согласен относительно “переписать”. Класс из одного виджета выглядит жутко. Просто МЕГАжутко.
А этот код - это вообще абзец…

Ну, зачем-то класс он же свой создавал Наверное, дополнить впоследствии хотел. В том виде, что есть, можно вообще классический tkinter.Text использовать и не париться с пользовательскими классами.

Отредактировано Ryoga (Фев. 7, 2014 10:44:46)

Офлайн

#6 Фев. 7, 2014 17:06:18

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

вызвать объект из другого объекта

Ryoga
Ну, зачем-то класс он же свой создавал
Ага. С одним атрибутом

Офлайн

  • Начало
  • » GUI
  • » вызвать объект из другого объекта[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version