簡體   English   中英

Python Tkinter OOP繼承

[英]Python Tkinter OOP Inheritance

我試圖從一個類繼承一些值到另一個。 我正在使用函數super繼承。 下面是我的問題的簡化版本。 謝謝你的幫助。

from tkinter import *
import random
class First(object):
    def __init__(self,master):
        super(First, self).__init__(master)
    def random(self):
        self._y = random.randint(11,20)
        self._x = random.randint(1,10)
    def random2(self):
        s = First(root)
        s.random()


class Second(Frame,First):
    def __init__(self,master):
        super(Second, self).__init__(master)
        self.grid()
        self.menuFrame = Frame(self)
        self.create_menu_widgets()
        self.menuFrame.grid()
    def create_menu_widgets(self):
          btnMainMenu = Button(self.menuFrame,font=("consolas",18,"bold"),text="Main Menu")
          btnMainMenu.pack()
    def print(self):
        print(self._y,self._x)



root = Tk()
x = Second(root)
x.random()
x.random2()
x.print()
root.configure(background   = 'green')
root.mainloop()

我繼續得到錯誤:

super(First, self).__init__(master)
TypeError: object.__init__() takes no parameters

請幫助我,我認為問題出在我有s = First(root)的地方。 感謝幫助。

當您在層次結構中最高的類上調用super時,它將成為object object是Python中所有對象的超類。 因此, super(First, self).__init__(master)將嘗試初始化object而不是您的任何類。 您可以使用Class.__mro__看到此繼承。 弄清楚我在說什么。

從對象繼承? 即使您未指定任何內容,默認情況下也會發生這種情況。 因此,我想您想從Frame繼承,因為object沒有任何意義。

因此,將您的代碼更改為此,它應該是固定的。

from tkinter import *
import random
class First(Frame): # changed here
    def random(self):
        self._y = random.randint(11,20)
        self._x = random.randint(1,10)
    def random2(self):
        s = First(root)
        s.random()


class Second(First): # changed here 
    def __init__(self,master):
        super(Second, self).__init__(master)
        self.grid()
        self.menuFrame = Frame(self)
        self.create_menu_widgets()
        self.menuFrame.grid()
    def create_menu_widgets(self):
          btnMainMenu = Button(self.menuFrame,font=("consolas",18,"bold"),text="Main Menu")
          btnMainMenu.pack()
    def print(self):
        print(self._y,self._x)

root = Tk()
x = Second(root)
x.random()
x.random2()
x.print()
root.configure(background   = 'green') # you cannot see this as your button fills everything
root.mainloop()

我在您的示例中看到了幾個問題。

1:

您要為x分配Second() ,然后調用x.random()x.random2() 這將不起作用,因為您的隨機方法僅存在於First()類中。

2:

不要將函數,方法,變量或屬性命名為與內置方法相同的名稱。 這會引起問題。

將您的def print(self)更改為def my_print(self)東西或不完全是print任何東西。 在討論此打印語句時,您僅在First()類中定義self._xself._y ,但嘗試在Second()類中進行打印。 這將永遠行不通。 self始終是對類對象的引用,而永遠不是對傳遞給該類的類控制器的引用。

現在,我在這里得到了您想要做的事情,並且我將重建您的代碼以顯示如何在類之間共享信息。

您不應在Frame類內部使用幾何管理器。 而是在類變量名稱上使用它。 這樣一來,您就可以在該類的任何幾何管理器之間進行選擇,而不必只遵循一種。

正如Vineeth指出的那樣,您不要對對象類使用晚餐。

下面的代碼將運行Second()類,然后當您要在First()類上引用隨機方法時,可以使用我添加到Second()的新方法來實現。 如果您有任何疑問,請告訴我。

最后一個更改是將tkinter導入為tk這將有助於防止意外覆蓋從tkinter導入的方法。

這是您的代碼的工作示例:

import tkinter as tk
import random


class First(object):
    def random(self):
        return "From First.Random!", random.randint(11,20), random.randint(1,10)

    def random2(self):
        return "From First.Random2!", self.random()


class Second(tk.Frame):
    def __init__(self, master):
        super(Second, self).__init__(master)
        self.menuFrame = tk.Frame(self)
        self.menuFrame.grid()
        tk.Button(self.menuFrame, font=("consolas", 18, "bold"), text="Main Menu").pack()

    def random(self):
        print(First().random())
    def random2(self):
        print(First().random2())


root = tk.Tk()
root.configure(background='green')

x = Second(root)
x.pack()
x.random()
x.random2()

root.mainloop()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM