Вероятно, это связано с наследованием. Класс Array не может быть получен вручную. Но как ни странно, вы можете объявить массив чего угодно и получить экземпляр System.Array, который строго типизирован, даже до того, как дженерики позволили вам иметь строго типизированные коллекции. Массив, по-видимому, является одной из тех магических частей рамки.
Также обратите внимание, что ни один из методов экземпляра, представленных в массиве, не массивно модифицирует массив. Кажется, что SetValue()
является единственным, что меняет что-либо. Класс Array предоставляет множество статических методов, которые могут изменять содержимое массива, например, Reverse () и Sort (). Не уверен, что это значимо - может быть, кто-то здесь может дать некоторое представление о том, почему это так.
Напротив, List
(чего не было в 1.0 каркасных днях) и таких классов, как ArrayList
(который был примерно в то время) - это просто запущенные классы мельниц, не имеющие особого значения в рамках. Они предоставляют общий метод экземпляра .Sort (), так что, когда вы унаследовали от этих классов, вы получили бы эту функциональность или могли бы переопределить ее.
Однако эти методы сортировки вышли из моды в любом случае поскольку методы расширения, такие как сортировка стиля Linq's .OrderBy (), стали следующей эволюцией.
- EDIT -
Другой, более циничный, и вы можете запросить и отсортировать массивы и списки и любой другой перечислимый объект с таким же механизмом. ответ может быть просто - , как это сделала Java , поэтому Microsoft сделала это так же в версии версии 1.0, поскольку в то время они были заняты игрой в догонялки.
Вы можете поместить изображение в Canvas
, а затем поместить в него Button
, поместив его в объект окна Canvas , который может содержать любой виджет Tkinter.
Дополнительные виджеты могут быть добавлены аналогичным образом, каждый внутри своего собственного оконного объекта Canvas
(так как они могут содержать только один виджет каждый). Вы можете обойти это ограничение, поместив виджет Frame
в окно Canvas
, а затем поместив другие виджеты в это .
Вот пример, показывающий, как отобразить один Button
:
from PIL import Image, ImageTk
import tkinter as tk
IMAGE_PATH = 'sfondo.png'
WIDTH, HEIGTH = 200, 200
root = tk.Tk()
root.geometry('{}x{}'.format(WIDTH, HEIGTH))
canvas = tk.Canvas(root, width=WIDTH, height=HEIGTH)
canvas.pack()
img = ImageTk.PhotoImage(Image.open(IMAGE_PATH).resize((WIDTH, HEIGTH), Image.ANTIALIAS))
canvas.background = img # Keep a reference in case this code is put in a function.
bg = canvas.create_image(0, 0, anchor=tk.NW, image=img)
# Put a tkinter widget on the canvas.
button = tk.Button(root, text="Start")
button_window = canvas.create_window(10, 10, anchor=tk.NW, window=button)
root.mainloop()
Снимок экрана:
[1115] [1121 ]
Редактировать
Хотя я не знаю способа сделать это в Frame
вместо Canvas
, вы можете получить свой собственный подкласс Frame
для сделать добавление нескольких виджетов проще. Вот что я имею в виду:
from PIL import Image, ImageTk
import tkinter as tk
class BkgrFrame(tk.Frame):
def __init__(self, parent, file_path, width, height):
super(BkgrFrame, self).__init__(parent, borderwidth=0, highlightthickness=0)
self.canvas = tk.Canvas(self, width=width, height=height)
self.canvas.pack()
pil_img = Image.open(file_path)
self.img = ImageTk.PhotoImage(pil_img.resize((width, height), Image.ANTIALIAS))
self.bg = self.canvas.create_image(0, 0, anchor=tk.NW, image=self.img)
def add(self, widget, x, y):
canvas_window = self.canvas.create_window(x, y, anchor=tk.NW, window=widget)
return widget
if __name__ == '__main__':
IMAGE_PATH = 'sfondo.png'
WIDTH, HEIGTH = 350, 200
root = tk.Tk()
root.geometry('{}x{}'.format(WIDTH, HEIGTH))
bkrgframe = BkgrFrame(root, IMAGE_PATH, WIDTH, HEIGTH)
bkrgframe.pack()
# Put some tkinter widgets in the BkgrFrame.
button1 = bkrgframe.add(tk.Button(root, text="Start"), 10, 10)
button2 = bkrgframe.add(tk.Button(root, text="Continue"), 50, 10)
root.mainloop()
Результат: