Как позвонить и закрыть виртуальную клавиатуру производства Tkinter с помощью сенсорного дисплея - PullRequest
0 голосов
/ 09 февраля 2020

У меня проблема с открытием и закрытием виртуальной клавиатуры, созданной с помощью Tkinter. Я создаю GUI, пользователь будет просматривать его с помощью сенсорного экрана, и пользователю нужно будет вводить записи.

Я пытался var_name.bind('FocusIn', callback) вызвать виртуальную клавиатуру и var_name.bind('FocusOut',callback) закрыть виртуальную клавиатуру, но при использовании обе виртуальные клавиатуры открываются, а затем закрываются сразу.

I надеюсь, вы, ребята, можете помочь мне, вот мой код:

import tkinter as tk

def select(entry, value, event):
    focused_entry.insert("end", event)
    pyautogui.press(event)
    global uppercase
    uppercase = False

    if value == "Space":
        value = ' '
    elif value == 'Enter':
        value = '\n'
    elif value == 'Tab':
        value = '\t'

    if value == "Backspace":
        if isinstance(entry, tk.Entry):
            entry.delete(len(entry.get())-1, 'end')
        #elif isinstance(entry, tk.Text):
        else: # tk.Text
            entry.delete('end - 2c', 'end')
    elif value in ('Caps Lock', 'Shift'):
        uppercase = not uppercase # change True to False, or False to True
    else:
        if uppercase:
            value = value.upper()
        entry.insert('end', value)
    return

def create(root, entry):
    alphabets = [
        ['`','1','2','3','4','5','6','7','8','9','0','-','=','Backspace'],
        ['Tab','q','w','e','r','t','y','u','i','o','p','[',']',"\\"],
        ['Caps Lock','a','s','d','f','g','h','j','k','l',';',"'",'Enter'],
        ['Shift','z','x','c','v','b','n','m',',','.','/','Shift'],
        ['Space']
    ]    

    global window
    window = tk.Toplevel(root)
    window.configure(background="cornflowerblue")
    window.geometry("+0+483")
    window.wm_attributes("-alpha", 0.7)

    for y, row in enumerate(alphabets):

        x = 0

        #for x, text in enumerate(row):
        for text in row:

            if text in ('Enter', 'Shift'):
                width = 18
                columnspan = 2
            elif text == 'Space':
                width = 124
                columnspan = 16
            elif text == 'Backspace':
                width = 10
                columnspan = 1
            elif text == '\\':
                width = 10
                columnspan = 1
            elif text == 'Tab':
                width = 10
                columnspan = 1
            elif text == '`':
                width = 10
                columnspan = 1
            elif text == 'Caps Lock':
                width = 10
                columnspan = 1
            else:                
                width = 4
                columnspan = 1

            tk.Button(window, text=text, width=width, 
                      command=lambda value=text: select(entry, value),
                      padx=3, pady=3, bd=12, bg="black", fg="white", takefocus = False
                     ).grid(row=y, column=x, columnspan=columnspan)

            x+= columnspan


# --- main ---

def remember_focus(event):
    global focused_entry
    focused_entry = event.widget

if __name__ == '__main__':
    root = tk.Tk()
    root.title('Test Keyboard')

    label = tk.Label(root, text='Test Keyboard')
    label.grid(row=0, column=0, columnspan=2)

    entry1 = tk.Entry(root)
    entry1.grid(row=1, column=0, sticky='news')
    entry1.bind("<FocusIn>", remember_focus)

    entry2 = tk.Entry(root)
    entry2.grid(row=2, column=0, sticky='news')
    entry2.bind("<FocusIn>", remember_focus)

    text1 = tk.Text(root)
    text1.grid(row=3, column=0, sticky='news')
    text1.bind("<FocusIn>", remember_focus)

    root.mainloop()

спасибо, сэр @furas, за помощь в создании виртуальной клавиатуры. Я отредактировал код и попробовал ответ Брайана Оукли здесь Tkinter проверьте, какая запись в последний раз была в фокусе

1 Ответ

1 голос
/ 11 февраля 2020

Вопрос : вызовите и закройте виртуальную клавиатуру с помощью сенсорного дисплея

Вместо вызовите и закройте , один раз создайте виртуальную клавиатуру и используйте Toplevel методы .deiconify() и .withdraw().

Не привязывайте событие '<FocusIn>' к каждому входному виджету, привязывайте к прикладному уровню , используя bind_all(....


Ссылка :


Базовая точка :

  • Использование .bind_all('<FocusIn>', ... до .deiconify()
  • Использование .bind_all('<Button-1>', ... до .withdraw()
# VKeyboard.py
import tkinter as tk


class VKeyboard(tk.Toplevel):
    def __init__(self, parent):
        super().__init__(parent)
        # Don't show the 'Toplevel' at instantiation
        super().withdraw()

        self.create()

        # Process all application == parent events
        parent.bind_all('<FocusIn>', self.on_event, add='+')
        parent.bind_all('<Button-1>', self.on_event, add='+')

    def on_event(self, event):
        w = event.widget

        # Don't process the own Button
        if w.master is not self:
            w_class_name = w.winfo_class()

            if w_class_name in ('Entry',):
                if self.state() == 'withdrawn':
                    self.deiconify()

                self.entry = w

            elif w_class_name in ('Button',):
                super().withdraw()
                w.focus_force()

    def create(self):
        # define the virtual keyboard `tk.Button`
        pass

Использование

import tkinter as tk
from VKeyboard import VKeyboard


class Kiosk(tk.Tk):
    def __init__(self):
        super().__init__()

        VKeyboard(self)

        tk.Entry(root).grid()
        tk.Button(root, text='withdraw').grid()


if __name__ == "__main__":
    Kiosk().mainloop()

Протестировано с Python: 3,5 - «TclVersion»: 8,6 «TkVersion»: 8,6 * 1 076 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...