मैंने अधिकांश उपलब्ध टिंकर स्क्रॉल किए गए टेक्स्ट स्टैक ओवरफ्लो पोस्ट देखे हैं जिनमें विरासत के विवरण शामिल हैं: विरासत ट्यूटोरियल a> और कक्षाओं के साथ विरासत। फिर भी, मुझे इस विशिष्ट उदाहरण में समझ में नहीं आ रहा है कि मुझे निम्न त्रुटि क्यों मिलती है:

    textBoxClass(self.parent).textDropIn(self.parent).insert(tk.INSERT,"This is the text to add.")
AttributeError: 'NoneType' object has no attribute 'insert'

मैं समझता हूं कि मेरे पास 'insert' की विशेषता मौजूद नहीं है, लेकिन मुझे समझ में नहीं आता कि textDropIn फ़ंक्शन में ScrolledText की मेरी क्लास डेफिनिशन कॉल के आधार पर गुण क्यों नहीं हैं class textBoxClass(tkst.ScrolledText):, हालांकि मुझे संदेह है कि यह अनुचित तात्कालिकता (?) है, यही कारण है कि फ़ंक्शन में ScrolledText विशेषताओं की विरासत उपलब्ध नहीं है।

मेरे एक अन्य भाग को संदेह है कि मुझे ScrolledText से someGui वर्ग के गुणों को वर्ग विधियों में कॉल करने के लिए इनहेरिट करना होगा, लेकिन मुझे यकीन नहीं है।

पूरा कोड:

from tkinter import *
from tkinter import ttk
import tkinter as tk
import tkinter.scrolledtext as tkst


class someGui(tk.Tk):
    def __init__(self,parent):
        self.parent=parent
        self.Window()
        textBoxInstance=textBoxClass(self.parent)

    def Window(self): 
        self.parent.configure(bg='white')
        self.parent.geometry("1000x500")
        self.parent.title("Example Window")
        self.someFrame = ttk.Frame(self.parent)
        self.someFrame.grid(row=0, column=0, sticky=(N,S,E,W))

        textBoxSeparate=textBoxClass(self.parent)
        self.someFunction()

    def someFunction(self):
        #otherstuff
        textBoxClass(self.parent).textDropIn(self.parent).insert(tk.INSERT,"This is the text to add.")

class textBoxClass(tkst.ScrolledText):
    def __init__(self,parent):
        self.root=parent
        self.textDropIn(self.root)

    def textDropIn(self,parent):
        self.someText = tkst.ScrolledText(master=self.root, wrap=tk.WORD, width=50, height=20)
        self.someText.grid(row=0, column=4, rowspan=7, columnspan=4, pady=20, padx=20)


def main(): 
    root =tk.Tk()
    sg=someGui(root)
    root.mainloop()

if __name__=='__main__':
    main()

इस प्रश्न को एक get() विशेषता कॉल के संदर्भ में None रिटर्न के साथ एक अन्य टिंकर पायथन पोस्ट के रूप में डुप्लिकेट के रूप में चिह्नित किया गया है, लेकिन मैंने उसी लाइन पृथक्करण संपादन को बनाया है जिसे उस उपयोगकर्ता को बिना अनुशंसित किया गया था समस्या को ठीक करना। अगर कोई विस्तार से समझा सकता है कि यह डुप्लिकेट क्यों है, तो मुझे प्रश्न को हटाने में खुशी होगी। लेकिन, मैं समझ नहीं पा रहा हूं कि ऐसा क्यों है।

ब्रायन के पहले उत्तर के आधार पर संपादित करें यह मेरी समझ थी। मैंने संपादन किए लेकिन रास्ते में कई त्रुटियों में भाग गया। मैंने tkst.ScrolledText को हटा दिया क्योंकि मुझे अनुचित रूप से इनहेरिट करने वाले गुण और कॉलिंग और इसके उदाहरण थे। मैंने parent को textDropIn फ़ंक्शन में एक विशेषता के रूप में और __init__ में textBoxClass परिभाषा में इसके संबंधित कॉल को हटा दिया। मैंने self.textBox=textBoxClass(self.parent) को someGui वर्ग के __init__ में भी जोड़ा है, लेकिन मैंने अपने संपादनों के आधार पर TypeError और RecursionError में भाग लिया है। वर्तमान में, यह वर्तमान संस्करण में कोड के साथ एक RecursionError है। जो कि self.textBox.textDropIn() के कारण है, जिसमें कोई तर्क पारित नहीं हुआ है।

from tkinter import ttk
import tkinter as tk
import tkinter.scrolledtext as tkst


class someGui(tk.Tk):
    def __init__(self,parent):
        self.parent=parent
        self.Window()
        self.textBox=textBoxClass(self.parent) #saving the instance 

    def Window(self): 
        self.parent.configure(bg='white')
        self.parent.geometry("1000x500")
        self.parent.title("Example Window")
        self.someFrame = ttk.Frame(self.parent)
        self.someFrame.grid(row=0, column=0, sticky='nesw') #changed sticky definition for tk requirements

        textBoxSeparate=textBoxClass(self.parent) # the initial inclusion of the textbox in the frame
        self.someFunction() #no input needed

    def someFunction(self):
        #otherstuff
        self.textBox.textDropIn() #there is no parent attribute in textDropIn, so I removed it
        self.textBox.insert(tk.INSERT, "Some test text.") #split call to two lines and changed to tk.INSERT

class textBoxClass(): #removed tkst.ScrolledText in class call because instance was created in textDropIn
    def __init__(self,parent):
        self.root=parent
        super().__init__() #kept receiving TypeError: object.__init__() takes no arguments, thus removed args
        self.textDropIn() #removed parent attribute from function call

    def textDropIn(self): #removed parent attribute from definition
        self.someText = tkst.ScrolledText(master=self.root, wrap=tk.WORD, width=50, height=20)
        self.someText.grid(row=0, column=4, rowspan=7, columnspan=4, pady=20, padx=20)


def main(): 
    root =tk.Tk()
    sg=someGui(root)
    root.mainloop()

if __name__=='__main__':
    main()
-2
whisperquiet 8 जिंदा 2019, 03:53

3 जवाब

सबसे बढ़िया उत्तर

एक मित्र के योगदान और टिप्पणीकारों ने जो कहा, उसके तत्वों को एकीकृत करने वाले मेरे अपने प्रयोग से, मैं कुछ हफ़्ते पहले अपनी समस्या के समाधान के लिए आया था।

मुझे पता है कि समाधान के लिए आवश्यक टिंकर विशेषता त्रुटि के आधार पर इसे कम कर दिया गया है, लेकिन विशेषता त्रुटि फिक्स के एक साधारण एकीकरण ने मेरी समस्या का समाधान नहीं किया और यह मेरे मूल प्रश्न से संबंधित एक अज्ञात त्रुटि थी। मेरे मूल प्रश्न का उत्तर देने के लिए यहां सबसे अच्छा उत्तर दिया गया है।

मुझे समझने में सबसे बड़ी समस्या थी super().__init__ textDropIn फ़ंक्शन में textBoxClass के भीतर कॉल करना। इससे पहले मुझे tkst.ScrolledText से विरासत में मिला था लेकिन मैं विजेट को गलत तरीके से बना रहा था।

अंतिम समाधान मुझे textBoxClass के क्लास इंस्टेंस पर कॉल करने और someGui क्लास से जुड़े सभी चाइल्ड फ़ंक्शंस में विंडो पर टेक्स्ट लिखने की अनुमति देता है, जो मेरा मूल लक्ष्य था।

मैंने पिछले कुछ विचारों को प्रतिबिंबित करने के लिए वहां टिप्पणी कोड छोड़ा है जो गैर-कार्यात्मक थे।

from tkinter import ttk
import tkinter as tk
import tkinter.scrolledtext as tkst


class someGui(tk.Tk):
    def __init__(self, parent):
        self.parent=parent
        self.textBox=textBoxClass(self.parent) #saving the instance
        self.Window()

    def Window(self): 
        print("window")
        self.parent.configure(bg='white')
        self.parent.geometry("1000x500")
        self.parent.title("Example Window")
        self.someFrame = ttk.Frame(self.parent)
        self.someFrame.grid(row=0, column=0, sticky='nesw') #changed sticky definition for tk requirements

        # textBoxSeparate=textBoxClass(self.parent) # the initial inclusion of the textbox in the frame
        # textBoxSeparate.place(relx=0.5, rely=0.025, anchor='nw') #added this so textBoxSeparate doesn't overlap textbox
        # textBoxSeparate.insert(tk.INSERT, "textBoxSeparate sample text")
        self.someFunction() #no input needed
        # self.newFunction()

    def someFunction(self):
        #Both of the following ways of adding text work
        self.textBox.textDropIn() #there is no parent attribute in textDropIn, so I removed it
        self.textBox.insert(tk.INSERT, "textbox sample text\n") #split call to two lines and changed to tk.INSERT
        self.newFunction()

    def newFunction(self):
        self.textBox.insert(tk.INSERT,"another line of text")

class textBoxClass(tkst.ScrolledText): 
    def __init__(self, parent):
        self.root = parent
        #super().__init__(...) allows this class to inherit the tkst.ScrolledText class. Therefore, initializing the textBoxClass 
        #will automaticaly allow it to have all the same methods/attributes as initializing tkst.ScrolledText(), in addition to the methods/attr you add below.
        super().__init__(master=self.root, wrap=tk.WORD, borderwidth=1, relief="solid",width=50, height=20) #added a border for better visualization
        #self.textDropIn() #removed parent attribute from function call

    def textDropIn(self): #removed parent attribute from definition
        self.grid(row=0, column=4, rowspan=7, columnspan=4, pady=20, padx=20)
        # self.insert(tk.INSERT, "textDropIn sample text\n")

def main(): 
    root =tk.Tk()
    sg=someGui(root)
    root.mainloop()

if __name__=='__main__':
    main()
0
whisperquiet 4 फरवरी 2019, 01:52
from tkinter import ttk
import tkinter as tk
import tkinter.scrolledtext as tkst


class SomeGui(tk.Tk):
    def __init__(self):
        super().__init__()

    self.textBox=TextBoxClass(self) #saving the instance 
    self.configure(bg='white')
    self.geometry("1000x500")
    self.title("Example Window")
    self.someFrame = ttk.Frame(self)
    self.someFrame.grid(row=0, column=0, sticky='nesw') #changed sticky definition for tk requirements

    self.someFunction() #no input needed

    def someFunction(self):
        #otherstuff
        self.textBox.textDropIn() #there is no parent attribute in textDropIn, so I removed it
        self.textBox.someText.insert(tk.INSERT, "here we go")

class TextBoxClass(tkst.ScrolledText): #removed tkst.ScrolledText in class call because instance was created in textDropIn
    def __init__(self,parent):
        self.root=parent
        tkst.ScrolledText.__init__(self) #kept receiving TypeError: object.__init__() takes no arguments, thus removed args
        self.textDropIn()

    def textDropIn(self): #removed parent attribute from definition
        self.someText = tkst.ScrolledText(master=self.root, wrap=tk.WORD, width=50, height=20)
        self.someText.grid(row=0, column=4, rowspan=7, columnspan=4, pady=20, padx=20)


def main(): 
    sg=someGui()
    sg.mainloop()

if __name__=='__main__':
    main()

ठीक है तो मैंने कुछ बदलाव किए हैं और यह सब आपकी someFunctionविधि के साथ काम कर रहा है। टिप्पणियों में ब्रायन के साथ बात करने के बाद मुझे एहसास हुआ कि हम आपके कुछगुई कक्षा में मूल वर्ग को प्रारंभ करना भूल गए थे जो शायद हमें प्राप्त होने वाली रिकर्सन त्रुटि का कारण था। शायद TextBoxClass को साफ करने का एक तरीका है जिसे मैं भी देख रहा हूं।

0
Gerald Leese 9 जिंदा 2019, 04:53

त्रुटि आपको बता रही है कि आप insert को एक ऐसी वस्तु पर कॉल करने का प्रयास कर रहे हैं जो None है। तो, आइए देखें कि आप insert को कहां कॉल कर रहे हैं:

textBoxClass(self.parent).textDropIn(self.parent).insert(tk.INSERT,"This is the text to add.")

त्रुटि संदेश के आधार पर हमें यह निष्कर्ष निकालना चाहिए कि textBoxClass(self.parent).textDropIn(self.parent) None है। और निश्चित रूप से, जब हम textDropIn विधि की परिभाषा को देखते हैं, तो यह स्पष्ट रूप से कुछ भी वापस नहीं करता है। क्योंकि यह स्पष्ट रूप से कुछ भी नहीं लौटाता है, यह None लौटाएगा। इस प्रकार, कोड वही है जैसे आपने None.insert(...) किया था, और इसलिए आपको जो त्रुटि मिलती है।

दो स्पष्ट समाधान हैं। यदि आप इस तरह के तरीकों को एक साथ श्रृंखलाबद्ध करने में सक्षम होना चाहते हैं (उदाहरण: .textDropIn(...).insert(...)), तो आपको यह सुनिश्चित करने की आवश्यकता है कि श्रृंखला में प्रत्येक चरण मूल वस्तु लौटाता है। आप इसे इस प्रकार कर सकते हैं:

def someFunction(self):
    #otherstuff
    textBoxClass(self.parent).textDropIn(self.parent).insert(tk.INSERT,"This is the text to add.")
    return self

दूसरी विधि उस एक लंबे कथन को दो में तोड़ना है:

textBoxClass(self.parent).textDropIn(self.parent)
textboxClass(self.parent).insert(tk.INSERT,"This is the text to add.")

हालांकि, textDropIn और insert को कॉल करने का यह उचित तरीका नहीं है। इसके बजाय, आपको इसे सीधे कक्षा के उदाहरण पर कॉल करने की आवश्यकता है। दुर्भाग्य से, आप इंस्टेंस के संदर्भ को सेव नहीं कर रहे हैं, इसलिए पहली बात यह है कि इंस्टेंस को सेव करके इसे ठीक किया जाए:

class someGui(tk.Tk):
    def __init__(self,parent):
        self.parent=parent
        self.Window()
        self.textBox = textBoxClass(self.parent)

फिर, आप उस उदाहरण पर विधियों को कॉल कर सकते हैं:

def someFunction(self):
    #otherstuff
    self.textBox.textDropIn(self.parent)
    self.textbox.insert(tk.INSERT,"This is the text to add.")

चूंकि आप कभी भी textDropIn में parent विशेषता का उपयोग नहीं करते हैं, इसलिए मेरा सुझाव है कि परिभाषा और कॉल दोनों से उस पैरामीटर को हटा दें।

साथ ही, यदि आप सभी वर्ग नामों को एक बड़े अक्षर से शुरू करते हैं तो आपके कोड को समझना आसान हो जाएगा। आपको textBoxClass से TextBoxClass और someGui को SomeGui में बदलना चाहिए। यह नामकरण परंपरा अजगर की दुनिया में सार्वभौमिक है। मानक नामकरण परंपराओं के बारे में अधिक जानकारी के लिए, PEP8 देखें।

एक और समस्या है। textBoxClass, दोनों ScrolledText से इनहेरिट कर रहे हैं और इसका एक उदाहरण बना रहे हैं। आपको एक या दूसरे को करना चाहिए। मैं यह नहीं बता सकता कि आप क्या हासिल करने की कोशिश कर रहे हैं, लेकिन मौजूदा वर्ग का विस्तार करने का सामान्य तरीका कुछ इस तरह है (super के उपयोगकर्ता को नोट करें):

class textBoxClass(tkst.ScrolledText):
    def __init__(self,parent):
        self.root=parent
        super().__init__(self, parent)
        self.textDropIn(self.root)

फिर भी कोड में एक और समस्या यह है कि आप दो बार टिंकर आयात कर रहे हैं:

from tkinter import *
...
import tkinter as tk

यह आपके कोड को समझने में बहुत कठिन बनाता है। आपको आयात करने का एक तरीका चुनना होगा और उस पर टिके रहना होगा। व्यक्तिगत रूप से मुझे लगता है कि दूसरा संस्करण सबसे अच्छा है क्योंकि यह पीईपी 8 के साथ-साथ पायथन के ज़ेन का पालन करता है (स्पष्ट से स्पष्ट स्पष्ट है)।

अंत में, एक और समस्या है। आप दो रूट विंडो बना रहे हैं, और एक टिंकर प्रोग्राम में केवल एक हो सकता है (बहुत ही असामान्य परिस्थितियों को छोड़कर, जो यह नहीं है)। एक तब बनाया जाता है जब आप root = tk.Tk() करते हैं, और दूसरा तब होता है जब आप sg=someGui(root) करते हैं, क्योंकि someGui को tk.Tk से विरासत में मिलता है। समस्या को जटिल करने के लिए आप सुपरक्लास __init__ विधि को ठीक से कॉल नहीं कर रहे हैं, इसलिए someGui इंस्टेंस ठीक से नहीं बनाया गया है। आपके अपडेट में आपके द्वारा लिखी गई रिकर्सन त्रुटि की जड़ यही है।

2
Bryan Oakley 9 जिंदा 2019, 06:21