Я работаю над круглой панелью навигации, и при щелчке по одному из пунктов меню он меняет цвет (и возвращается к исходному, если щелкнуть по другому).
Используя метод create_arc
, ясоздал границы для каждой кнопки (представлены в виде текста), и, используя словарь, я пытаюсь сохранить текст кнопки в качестве ключа, а теги кнопки и дуги - в качестве значений, представляющих пункты меню панели навигации.
Однако, несмотря на то, что каждый текстовый элемент хранится с правильной дугой, при нажатии на одну из опций неправильная дуга выделяется.Это самое близкое, что я понял, к полной работе:
import tkinter as tk
import math
class CircularNavbar(tk.Frame):
def __init__(self, parent, font='arial', fontsize=20, textcolour='red',
highlightcolour='blue', selectcolour='light blue',
btncolour='white', outlinecolour='black', navsize=500,
btnwidth=50, options=[], *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.font, self.fontsize = font, fontsize
self.textcolour, self.highlightcolour = textcolour, highlightcolour
self.selectcolour = selectcolour
self.btncolour, self.outlinecolour = btncolour, outlinecolour
self.navsize, self.btnwidth, self.max_btns = navsize, btnwidth, len(options)
self._children, self.options, self.btns = {}, options, []
self.canvas = tk.Canvas(self, width=navsize, height=navsize)
self.canvas.grid()
d = 360 // self.max_btns
for count in range(-d//2, 360-d//2, d):
btn = self.canvas.create_arc(navsize*0.1, navsize*0.1, navsize*0.9,
navsize*0.9, outline=btncolour,
start=count, extent=d-1, style=tk.ARC,
width=btnwidth*0.9, tag=count,
activefill=selectcolour,
disabledfill=btncolour)
self.btns.append(btn)
for count in range(self.max_btns):
btn = self.canvas.create_text(navsize//2, navsize*0.1, font=(font, fontsize),
fill=textcolour, activefill=highlightcolour,
text=self.options[count],
tag=self.options[count])
self._position(btn, count)
self._children[self.options[count]] = [btn, self.btns[count-7]]
self.canvas.tag_bind(btn, '<Button-1>', lambda event,
text=self.options[count]: self._setindicator(event, text))
def _position(self, btn, count):
angle = count*(360/self.max_btns)
x = -math.sin(math.radians(angle)) * self.navsize*0.4 + self.navsize//2
y = -math.cos(math.radians(angle)) * self.navsize*0.4 + self.navsize//2
self.canvas.coords(btn, x, y)
self.canvas.itemconfig(btn, angle=angle)
self.canvas.tag_raise(btn)
def _setindicator(self, event=None, text=None):
for option, btns in self._children.items():
if text == option:
self.canvas.itemconfig(btns[1], state='disabled',
outline=self.selectcolour)
self.canvas.itemconfig(btns[0], state='disabled',
fill=self.outlinecolour)
else:
self.canvas.itemconfig(btns[1], state='normal',
outline=self.btncolour)
self.canvas.itemconfig(btns[0], state='normal',
fill=self.textcolour)
win.update()
options = ['Play', 'Settings', 'Exit', 'Buy', 'Boards', 'Help', 'Shop', 'Quit']
win = tk.Tk()
Nav = CircularNavbar(win, font='console', fontsize=22, textcolour='#369efb',
highlightcolour='blue', selectcolour='#68b6fc',
btncolour='#0478e1', outlinecolour='#035096', navsize=700,
btnwidth=70, options=options)
Nav.grid()
win.mainloop()
Игнорируя плохое вращение текста, приведенный выше фрагмент почти работает, за исключением последней кнопки ('выход')- это не меняет цвет.Кажется, есть проблема с тем, как каждый текстовый элемент связан с дугой.
Дуги расширяются против часовой стрелки, поэтому я попытался создать кнопки аналогичным образом против часовой стрелки, чтобы связать каждую дугу с текстовым элементом, но я 'я не уверен, где я ошибаюсь с окончательным текстовым элементом.
Я также попытался сторнировать список self.btns
, инвертируя приращение первого цикла for (и пытаясь -count
, count-7
и т. д. - при добавлении дуги в словарь: [btn, self.btns[count-7]]
) и использовании кнопок против часовой стрелки или по часовой стрелке, но все безрезультатно ...