Çoklu miras almak

Merhaba, bir class içerisinde birden fazla miras alıp diğer defler de nasıl çağırabilirim.

class Deneme(ui.ThinBoard,ui.Button):
	def __init__(self):
		super(Deneme, self).__init__(self)
		self.__board()
		#self.__button()
	def __board(self):
		import wndMgr
		## Create Thinboard
		self.thinBoardWidth = wndMgr.GetScreenWidth()-30
		self.thinBoardHeight = 50
		self.SetSize(self.thinBoardWidth, self.thinBoardHeight)
		self.SetTop()
		self.SetWindowHorizontalAlignCenter()
		self.ThinBoard = self[0]
		self.Show()

	def __button(self):
		self[1].SetParent(self[0])
		self[1].SetWindowVerticalAlignTop()
		self[1].SetPosition(self.thinBoardWidth-15,15)
		self[1].SetUpVisual('d:/ymir work/ui/public/close_button_01.sub')
		self[1].SetOverVisual('d:/ymir work/ui/public/close_button_02.sub')
		self[1].SetDownVisual('d:/ymir work/ui/public/close_button_03.sub')
		self[1].SetText('')
		self[1].SetToolTipText('Close')
		self[1].Button = self[1]
		self[1].Show()

Merhaba,

self[1] yazarak miras aldığınız diğer sınıfa mı ulaşmak istediniz?

super(Deneme, self).__init__(self) şu ifadede de bir hata var.

Ne yapmaya çalıştığınızı daha açık bir şekilde anlatabilir misiniz acaba?

Evet miras aldığım diğer sınıfı yani self[1] = ui.Button olarak düşündüm fakat işe yaramadı.

Eğer miras aldığınız sınıfların metodları bu kadar çok çakışıyorsa miras almayın. Button ve ThinBoard örneklerini nitelik olarak saklayın.

1 Beğeni

Aşağıdaki şekilde kodları düzenledim.

class Board(ui.ThinBoard):
	def __init__(self,width=None,height=None):
		super(Board,self).__init__()
		self.button = ui.Button()
		self.textline = ui.TextLine()
		self.width = wndMgr.GetScreenWidth() - width
		self.height = height
		if self.width and self.height is not None:
			self.ThinBoard = self
			self.board()

	def board(self): # Create board
		self.SetSize(self.width, self.height)
		self.SetTop()
		self.SetWindowHorizontalAlignCenter()
		self.Show()

	def buttons(self,text,x,y): # Create button
		self.button.SetParent(self)
		self.button.SetUpVisual('d:/ymir work/ui/public/large_button_01.sub')
		self.button.SetOverVisual('d:/ymir work/ui/public/large_button_02.sub')
		self.button.SetDownVisual('d:/ymir work/ui/public/large_button_03.sub')
		self.button.SetText(text)
		self.button.SetPosition(x,y)
		self.button.Show()
		self.button.button = self.button

	def text(self,text): # Create textline
		self.textline.SetParent(self)
		self.textline.SetHorizontalAlignCenter()
		self.textline.SetFontColor(2, 1, 0)
		self.textline.SetFontName("Arial:15")
		self.textline.SetText(text)
		self.textline.SetPosition(self.width/2,self.height/3)
		self.textline.Show()
		self.textline.textline = self.textline

	def edittext(self,text): # Edit textline
		self.textline.SetText = text

Kodunuzu çalıştıramıyorum ama bu daha iyi görünüyor sanki. @EkremDincel’in söylediklerine de katılıyorum. Eğer metotlar veya nitelikler çakışıyor ise çoklu miras almak yerine, kullanılacak widgetlerin örneklerini nitelik olarak saklamak size daha çok hareket imkanı sağlar. Çünkü çakışma varsa, __init__ metodu çağrılan son sınıfın metotları, __init__ metodu önce çağrılmış olan sınıfın metotlarının üzerine yazılır ve ilk miras aldığınız sınıf üzerinde çok fazla işlem yapamazsınız. Ancak aşağıdaki gibi, neyi hangi satırda yazdığınıza dikkat ederek, sizi kısıtlayacak bir şekilde miras alınan sınıflarla işlem yapabilirsiniz, ki açıkçası bu yaklaşımı pek önermem. Oysa sınıfları birer örnek niteliği olarak kullanmak size daha çok hareket alanı sağlar.

#!/usr/bin/python3.8
# -*- coding: utf-8 -*-

import tkinter as tk


class Button(tk.Button):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack()
        
        
class Text(tk.Text):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pack()


class ButtonText(Button, Text):
    def __init__(self, text, *args, **kwargs):
        Button.__init__(self, text=text, *args, **kwargs)
        # Buradaki self Button()'u temsil ediyor.
        self.configure(
            command=self.command
        )
        Text.__init__(self, *args, **kwargs)
        
    def command(self):
        # Buradaki self ise Text()'i temsil ediyor.
        self.insert("end", "hello")
        
        
root = tk.Tk()
ButtonText(master=root, text="hello")
root.mainloop()
2 Beğeni

Bilgilendirdiğiniz için teşekkür ederim, bir oyun üzerine kodladığım için ***args, kwargs kullanamıyorum ( Desteklemiyor ) . Üstelik SetParent yani ebeveyn tanımlamak durumundayım dolayısıyla da aynı class içerisinde yer almalılar **( args, kwargs olmadığı için ). Aşağıdaki kod nesnel bir yaklaşımın dışarısında mı ?

class Board(ui.ThinBoard):
	def __init__(self,width,height,x=0,y=0):
		super(Board,self).__init__()
		self.ThinBoard = self
		self.width = width
		self.height = height
		self.x = x
		self.y = y
		self.board()

	def board(self): # Create board
		if self.x and self.y is 0:
			self.SetTop()
			self.width = wndMgr.GetScreenWidth() - self.width
			self.SetSize(self.width, self.height)
			self.SetWindowHorizontalAlignCenter()
		else:
			self.SetPosition(int(self.x),int(self.y))
			self.SetSize(self.width, self.height)
		self.Show()

	def button(self,text,x,y,event): # Create button
		self.btn = ui.Button()
		self.btn.SetParent(self)
		self.btn.SetUpVisual('d:/ymir work/ui/public/large_button_01.sub')
		self.btn.SetOverVisual('d:/ymir work/ui/public/large_button_02.sub')
		self.btn.SetDownVisual('d:/ymir work/ui/public/large_button_03.sub')
		self.btn.SetText(text)
		self.btn.SetEvent(event)
		self.btn.SetPosition(x,y)
		self.btn.Show()
		self.btn.Button = self.btn

	def text(self,text,x=0,y=0): # Create textline
		if x and y is 0:
			x =  self.width / 2
			y = self.height / 3
		self.txt = ui.TextLine()
		self.txt.SetParent(self)
		self.txt.SetHorizontalAlignCenter()
		self.txt.SetFontName("Arial:15")
		self.txt.SetText(text)
		self.txt.SetPosition(x,y)
		self.txt.Show()
		self.txt.TextLine = self.txt

	def edittext(self,text,color=None): # Edit textline
		if color == "r": # Red
			self.txt.SetFontColor(2, 0, 0)
		elif color == "g": # Green
			self.txt.SetFontColor(5, 2, 0)
		elif color == "b": # Blue
			self.txt.SetFontColor(0, 6, 2)
		elif color == "y": # Yellow
			self.txt.SetFontColor(2, 2, 0)
		self.txt.SetText = text






border = Board(width=300,height=50)
border.text(text="Lorem ipsum dolor,Lorem ipsum dolor")

border2 = Board(width=50,height=150,x=3,y=200)
border2.button(text="Rota Kaydet",event=Rotation,x=30,y=15)
border2.button(text="Baslat",event=envanter,x=120,y=15)
border2.button(text="Pazar",event=Shop,x=560,y=15)
border2.button(text="Hizli Cikis",event=app.Exit,x=650,y=15)

Niye böyle ifadeler yazma gereği duydunuz?

Ayrıca, self.btn, ve self.txtin, __init__ metodunun dışında tanımlanması pek tavsiye edilmez.

self.btn.Button = self.btn gibi ifadeler kullanma sebebim global alana taşımak, ifadeler olmadan yalnızca son eklediklerim görünüyor. Ayrıca self.btn , ve self.txt in, __init_ dışına tanımlama sebebim her button veya text oluşturduğumda bir parent oluşturmak istemiyorum. Var olan parent üzerinden işlem yapmak için bu yolu tercih ettim.