【问题标题】:Python 3.x tkinter: Buttons of specific shapes or Button overlayPython 3.x tkinter:特定形状的按钮或按钮覆盖
【发布时间】:2019-01-17 21:48:42
【问题描述】:

我是 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()

另外,如果我的代码到目前为止是草率的,我将不胜感激更正/反馈

【问题讨论】:

  • 你不需要global listofnamelistofname 已经是全局的,所以这完全没用。 listofkeys 也是如此。
  • 要在其他按钮上定位按钮,请查看 place 几何管理器。

标签: python python-3.x button tkinter


【解决方案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,这给出了

您可以对此进行调整,但实际上我非常喜欢这个结果。

【讨论】:

    【解决方案2】:

    使用place 进行定位,使用widget.tkraise() 将特定按钮置于前面。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-18
      • 1970-01-01
      • 1970-01-01
      • 2017-07-23
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 2015-02-02
      相关资源
      最近更新 更多