私はかなりpythonとtkinterの新機能です。私は私のスキルを構築するために努力していますので、私はラズベリーパイをプログラムすることができます。私の現在の問題は私に悩まされました:私は、エントリフィールドをクリックすると、ダイアログボックス(画面キーボード)を表示したい。呼び出し可能なTkinterのToplevelポップアップダイアログ
私はこれを実現するためにいくつかの方法を試しました。キーボードを最初に表示するか、まったく表示しないようにすることができます。しかし、クリックイベントではありません。私は、キーボードクラスがそれ自身で作業していることを知っているので、私はそれをどのように呼び出すのか(popout.pyの29行目)でなければなりません。
Exception in Tkinter callback
Traceback (most recent call last):
File "E:\Programs\Python3\lib\tkinter\__init__.py", line 1533, in __call__
return self.func(*args)
TypeError: keyboard() takes from 1 to 3 positional arguments but 4 were given
または
Exception in Tkinter callback
Traceback (most recent call last):
File "E:\Programs\Python3\lib\tkinter\__init__.py", line 1533, in __call__
return self.func(*args)
TypeError: 'Keyboard' object is not callable
を私は本当にこれらの例外を取得するために何が起こっているのか理解していない:私は、私が実装しようとする方法に基づいて2つのエラーメッセージのいずれかを取得します。以下は私のコードです:
Popup.py
import tkinter as tk
import keyboard as k
#
from time import sleep
# needs Python25 or higher
from functools import partial
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.pack()
#variable to update counter text
self.num = tk.StringVar()
self.create_widgets()
def create_widgets(self):
# button to start counting
self.startbtn = tk.Button(self)
self.startbtn["text"] = "Start counting\n(Click)"
self.startbtn["command"] = self.counting
self.startbtn.pack(side="top")
#Label to view counter
self.counter = tk.Label(self, textvariable=self.num)
self.counter.pack()
#Entry box
self.e = tk.StringVar()
self.entry = tk.Entry(self, textvariable=self.e)
#launch_kbd = partial(self.keyboard, "MyKeyboard", self.e)
#self.entry.bind("<Button-1>", launch_kbd)
self.entry.bind("<Button-1>", k.Keyboard(self, "MyKeyboard", self.e))
self.entry.pack()
#Exit
self.quit = tk.Button(self, text="Quit", fg="red", command=root.destroy)
self.quit.pack(side="bottom")
#count for 10 seconds
def counting(self):
self.startbtn["state"] = "disabled"
root.update()
#loop from 1-10
for x in range(1,11):
self.num.set(str(x)) #update the label's variable
root.update() #important to make changes visible
sleep(1) #sleep for 1 second
#Clear text when done
self.num.set("")
self.startbtn["state"] = "enabled"
root.update()
#def keyboard(self, title=None, target=None):
# k.Keyboard(self, title, target)
'''
This starts the root window
'''
root = tk.Tk()
root.title("myGUI")
root.geometry("200x100")
app = Application(master=root)
app.mainloop()
keyboard.py
'''
# Built with examples from:
- http://effbot.org/tkinterbook/tkinter-dialog-windows.htm
- https://www.daniweb.com/programming/software-development/threads/300867/on-screen-keyboards-in-tkinter
# Desc: Creates a pop-up on-screen Keyboard for text entry.
Writes entry to Target upon pressing Enter.
'''
# use tkinter for GUI application
import tkinter as tk
# used for button click
from functools import partial
class Keyboard(tk.Toplevel):
def __init__(self, parent, title=None, target=None):
tk.Toplevel.__init__(self, parent, bg='black')
# associate this window with a parent window
self.transient(parent)
if title:
self.title(title)
if target:
self.target = target
self.init_txt = target.get()
self.parent = parent
body = tk.Frame(self)
self.body(body)
body.pack(padx=5, pady=5)
self.buttonbox()
#make the dialog modal
self.grab_set()
# safely handle WM_DELETE_WINDOW event
self.protocol("WM_DELETE_WINDOW", self.close)
# position the dialog relative to the parent window
self.geometry("+%d+%d" % (parent.winfo_rootx()+50, parent.winfo_rooty()+50))
# Hold captive control until window is closed
# prevent parent from accepting input while window is open
self.wait_window(self)
# END Init
def body(self, master):
#Text input at the top
self.txt = tk.StringVar()
self.txt.set(self.init_txt)
self.tx = tk.Entry(self, bg='black', fg='white', insertbackground='gray', insertwidth=2, textvariable=self.txt)
self.tx.focus_set()
self.tx.pack(fill="x", padx=5, pady=5)
def buttonbox(self):
# create a frame for the keypad buttons
bf = tk.Frame(self)
bf.pack()
# button layout
btn_list = [
'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', ',', '.', '?',
'Num', '+', '-', ' ', ' ', ' ', '<-', '->', 'BKS', 'ETR', ]
# create and position all buttons with a for-loop
# r, c used for row, column grid values
r = 1
c = 0
n = 0
# list(range()) needed for Python3
btn = list(range(len(btn_list)))
for label in btn_list:
# partial takes care of function and argument
cmd = partial(self.click, label)
# create the button (and style it)
btn[n] = tk.Button(bf, text=label, width=5, height=3, command=cmd, bg='#333333', fg='white', activebackground='#666666', activeforeground='white')
# position the button
btn[n].grid(row=r, column=c)
# increment button index
n += 1
# update row/column position
c += 1
if c > 9:
c = 0
r += 1
def click(self, btn):
if btn == 'Num':
# Switch to number pad
pass
elif btn == '<-':
# Move cursor to the left 1 character
self.tx.icursor(self.tx.index('insert')-1)
elif btn == '->':
# Move cursor to the right 1 character
#icursor(index)
self.tx.icursor(self.tx.index('insert')+1)
elif btn == 'BKS':
# truncate entry by 1 character
self.tx.delete(self.tx.index('insert')-1)
elif btn == 'ETR':
# return entered value to the input
self.apply()
self.close()
else:
# DEFAULT: append entry with btn
self.tx.insert('insert', btn)
def close(self, event=None):
# put focus back to the parent window
self.parent.focus_set()
self.destroy()
def apply(self):
self.target.set(self.tx.get())
# if called directly
if __name__ == "__main__":
root = tk.Tk()
t = tk.StringVar()
k = Keyboard(root, "MyKeyboard", target=t)
print(t.get())