【问题标题】:How to use overlay Vkeyboard on Canvas in tkinter?如何在 tkinter 的 Canvas 上使用覆盖 Vkeyboard?
【发布时间】:2020-12-22 08:20:45
【问题描述】:

我有一个使用grid 用tkinter 编写的Vkeyboard 代码。我想在我的画布和背景图像上实现它。

以下是我的代码。

from tkinter import *


Keyboard_App = Tk()

canvas = Canvas(Keyboard_App, width=400, height=400)
canvas.pack(side="top", fill="both", expand=True)

background = PhotoImage(file="Images/background.png")
canvas.create_image(400,400,image=background, tags="B")

buttons = [
    '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '=',
    'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '<-',
    'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '"',
    'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 'SHIFT',
    ' Space ',
]
curBut = [-1,-1]
buttonL = [[]]
entry = Text(Keyboard_App, width=97, height=8)
entry.grid(row=0, columnspan=15)

varRow = 1
varColumn = 0

def leftKey(event):
    if curBut == [-1,-1]:
        curBut[:] = [0,0]
        buttonL[0][0].configure(highlightbackground='red')
    elif curBut[0] == 4:
        buttonL[curBut[0]][curBut[1]].configure(highlightbackground='#d9d9d9')
        curBut[:] = [0,10]
        buttonL[0][10].configure(highlightbackground='red')
    else:
        buttonL[curBut[0]][curBut[1]].configure(highlightbackground='#d9d9d9')
        curBut[:] = [curBut[0], (curBut[1]-1)%11]
        buttonL[curBut[0]][curBut[1]%11].configure(highlightbackground='red')

def rightKey(event):
    if curBut == [-1,-1]:
        curBut[:] = [0,0]
        buttonL[0][0].configure(highlightbackground='red')
    elif curBut[0] == 4:
        buttonL[curBut[0]][curBut[1]].configure(highlightbackground='#d9d9d9')
        curBut[:] = [0,0]
        buttonL[0][0].configure(highlightbackground='red')
    else:
        buttonL[curBut[0]][curBut[1]].configure(highlightbackground='#d9d9d9')
        curBut[:] = [curBut[0], (curBut[1]+1)%11]
        buttonL[curBut[0]][curBut[1]%11].configure(highlightbackground='red')

def upKey(event):
    if curBut == [-1,-1]:
        curBut[:] = [0,0]
        buttonL[0][0].configure(highlightbackground='red')
    elif curBut[0] == 0:
        buttonL[curBut[0]][curBut[1]].configure(highlightbackground='#d9d9d9')
        curBut[:] = [(curBut[0]-1)%5, 0]
        buttonL[curBut[0]][curBut[1]%11].configure(highlightbackground='red')
    else:
        buttonL[curBut[0]][curBut[1]].configure(highlightbackground='#d9d9d9')
        curBut[:] = [(curBut[0]-1)%5, curBut[1]]
        buttonL[curBut[0]][curBut[1]%11].configure(highlightbackground='red')

def downKey(event):
    if curBut == [-1,-1]:
        curBut[:] = [0,0]
        buttonL[0][0].configure(highlightbackground='red')
    elif curBut[0] == 3:
        buttonL[curBut[0]][curBut[1]].configure(highlightbackground='#d9d9d9')
        curBut[:] = [(curBut[0]+1)%5, 0]
        buttonL[curBut[0]][curBut[1]%11].configure(highlightbackground='red')
    else:
        buttonL[curBut[0]][curBut[1]].configure(highlightbackground='#d9d9d9')
        curBut[:] = [(curBut[0]+1)%5, curBut[1]]
        buttonL[curBut[0]][curBut[1]%11].configure(highlightbackground='red')

def select(value, x, y):
    if curBut != [-1,-1]:
        buttonL[curBut[0]][curBut[1]].configure(highlightbackground='#d9d9d9')
    curBut[:] = [x,y]
    buttonL[x][y].configure(highlightbackground='red')
    if value == "<-":
        input = entry.get("1.0", 'end-2c')
        entry.delete("1.0", END)
        entry.insert("1.0", input, END)

    elif value == " Space ":
        entry.insert(END, ' ')

    elif value == "Tab":
        entry.insert(END, '   ')

    else:
        entry.insert(END, value)

for button in buttons:
    if button != " Space ":
        but = Button(Keyboard_App, text=button, width=5, bg="#000000", fg="#ffffff", highlightthickness=4, 
                       activebackground="#ffffff", activeforeground="#000000", relief="raised", padx=12,
                       pady=4, bd=4, command=lambda x=button, i=varRow-1, j=varColumn: select(x, i, j))
        buttonL[varRow-1].append(but)
        but.grid(row=varRow, column=varColumn)

    if button == " Space ":
        but = Button(Keyboard_App, text=button, width=60, bg="#000000", fg="#ffffff", highlightthickness=4, 
                       activebackground="#ffffff", activeforeground="#000000", relief="raised", padx=4,
                       pady=4, bd=4, command=lambda x=button, i=varRow-1, j=varColumn: select(x, i, j))
        buttonL[varRow-1].append(but)
        but.grid(row=6, columnspan=16)

    varColumn += 1
    if varColumn > 10:
        varColumn = 0
        varRow += 1
        buttonL.append([])

Keyboard_App.bind('<Left>', leftKey)
Keyboard_App.bind('<Right>', rightKey)
Keyboard_App.bind('<Up>', upKey)
Keyboard_App.bind('<Down>', downKey)
Keyboard_App.mainloop()

这会导致错误提示 _tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack,因为我不能在单个帧中同时使用 gridpack。我对代码很困惑,比如我应该如何解决这个问题。谁能给我一个线索,如何使用我的代码走上正轨?谢谢。

【问题讨论】:

    标签: python python-3.x tkinter tkinter-canvas tkinter-entry


    【解决方案1】:

    正如错误所述,您根本不能在同一帧中同时使用gridpack。您需要删除对.pack() 的调用才能使其正常工作。

    canvas = Canvas(Keyboard_App, width=400, height=400)
    canvas.place(x=0, y=0, relwidth=1, relheight=1)
    
    background = PhotoImage(file="Images/background.png")
    canvas.create_image(400,400,image=background, tags="B")
    

    您还需要致电.place() 以便它知道在您的窗口上显示的位置。 relwidthrelweight 只是相对于主对象的宽度和重量,在这里是可选的。

    请注意,如果您的旧代码确实管理它,这不会正确调整图像大小。我建议使用库 PIL 如果您想调整它的大小,我可以向您展示适用于您的情况的代码;我相信只需使用您的PhotoImage 也可以,但不实用。

    【讨论】:

    • 感谢您的评论!通过这样做,它解决了该错误,但我们可以先获取背景图像,然后再获取 VKeyboard 和 Entry 吗? \
    • @Deepakpal 我的错,我忘了你有背景图片。我会尽快编辑它。
    • @Deepakpal 编辑并添加了更多细节!
    • 非常感谢!它的工作!只是有一个问题,当我尝试用canvas.create_text 替换Entry 时,它显示了这个错误-> self.canvas_textbox.insert(END, value) AttributeError: 'int' object has no attribute 'insert'
    • @Deepakpal 您的代码中没有canvas_textbox,但正如错误所示,它是一个int,您试图在其上调用一个名为.insert() 的方法,但显然没有因为它只是一个数字。
    猜你喜欢
    • 1970-01-01
    • 2021-12-05
    • 2021-10-01
    • 1970-01-01
    • 2022-08-17
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    相关资源
    最近更新 更多