我是tkinter的新手,也是python的新手,所以我决定使用tkinter作为实践来构建“合成器”。到目前为止,它可以正常工作,但我不知道如何使键盘看起来像实际的钢琴键盘,即缺少黑键。有没有一种方法可以在Tkinter中塑造纽扣形状,以便我可以挤压黑色 中间的按键还是黑色按键覆盖在白色按键上方?
到目前为止,我的代码:
from tkinter import *
from functools import partial
import pygame
pygame.mixer.init()
#directory name where sounds are
direc='/Users/nol975/Desktop/tiny-piano00/Piano-'
listofnames=['A4','A5','D#4','D#5','C1','F#5','C3','C4','C5','C6','F#4']
listofkeys=[direc+x+'.wav' for x in listofnames]
def clicked(a):
(pygame.mixer.Sound(listofkeys[a]).play())
#**********GUI**********
root=Tk()
root.title('My cool synth')
#keyboard
synthframe=Frame(root).pack(side= BOTTOM, anchor='n')
for i in range(len(listofnames)):
Button(synthframe,text=listofnames[i], command=partial(clicked,i)).pack(side=LEFT, fill=BOTH, expand=1)
#Menu bar on top
menu = Menu(root)
root.config(menu=menu)
submenu = Menu(menu)
menu.add_cascade(label='File', menu=submenu)
submenu.add_command(label='Quit', command=root.destroy)
root.mainloop()
另外,如果我到目前为止的代码草率,我将不胜感激。
答案 0 :(得分:1)
我没有为您的确切示例量身定做,但我尝试使用下图中绘制的网格将钢琴键建模为网格。每个白色键由三列和两行(蓝色轮廓)组成,每个黑色键由两列和一行(绿色轮廓)组成。当然,黑键应该放在白键的上方。
使用此模型,您可以将所有按键(首先是白色按键,然后是黑色按键)放置在具有定义大小的网格上,并且黑色按键相对于白色按键向右移动两行。使用grid()
将一个按钮(部分地)放在另一个按钮上是完美的。我定义了一个列表([1, 1, 0, 1, 1, 1, 0]
来指示是否应将黑键放在白键之后。
import tkinter as tk
def clicked(color, num):
print(color + ': ' + str(num))
root = tk.Tk()
scales = 3
root.geometry('{}x200'.format(300 * scales))
white_keys = 7 * scales
black = [1, 1, 0, 1, 1, 1, 0] * scales
for i in range(white_keys):
tk.Button(root, bg='white', activebackground='gray87', command=lambda i=i: clicked('White', i)).grid(row=0, column=i*3, rowspan=2, columnspan=3, sticky='nsew')
for i in range(white_keys - 1):
if black[i]:
tk.Button(root, bg='black', activebackground='gray12', command=lambda i=i: clicked('Black', i)).grid(row=0, column=(i*3)+2, rowspan=1, columnspan=2, sticky='nsew')
for i in range(white_keys * 3):
root.columnconfigure(i, weight=1)
for i in range(2):
root.rowconfigure(i, weight=1)
root.mainloop()
使用scales=3
,这给出了
您可以对此进行足够的调整,但实际上我很喜欢结果。
答案 1 :(得分:0)
使用place
进行定位,并使用widget.tkraise()
将特定的按钮置于前面。