Python Tkinter OOP Наследование - PullRequest
       5

Python Tkinter OOP Наследование

0 голосов
/ 25 октября 2018

Я пытаюсь наследовать некоторые значения от одного класса к другому.Я использую функцию супер для наследования.Ниже приведен упрощенный вариант моей проблемы.Спасибо за помощь.

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 = Первый (root).Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Я вижу несколько проблем в вашем примере.

1:

вы назначаете Second() на x, но затем вызываете x.random() и x.random2().Это не будет работать, так как ваши случайные методы существуют только в классе First().

2:

Не называйте функцию, метод, переменную или атрибут так же, как встроенныйметод.Это вызовет проблемы.

Измените def print(self) на что-то вроде def my_print(self) или что-то, что не совсем print.Пока мы говорим об этом операторе печати, вы только определяете self._x и self._y в своем классе First(), но пытаетесь распечатать их в своем классе Second().Это никогда не сработает.self всегда является ссылкой на объект класса и никогда не является ссылкой на контроллер класса, который был передан в класс.

Теперь я получаю то, что вы пытаетесь сделать здесь, и я перестрою ваш код, чтобы показатькак делиться информацией между классами.

Вы не должны использовать менеджер геометрии внутри класса Frame.Вместо этого используйте его в имени переменной класса.Это позволит вам выбирать между любым менеджером геометрии для класса вместо того, чтобы придерживаться только одного вида.

Как указывал Вайнс, вы не используете ужин для класса объекта.

Приведенный ниже код будетзапустите класс 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()
0 голосов
/ 25 октября 2018

Когда вы вызываете 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...