#!/usr/bin/env python3 import sys import os from qtpy import QtGui, QtWidgets, uic from qtpy.QtCore import Qt, QEvent, Signal from qtvcp.core import Info, Path from qtvcp import logger LOG = logger.getLogger(__name__) PATH = Path() class VirtualKeyboard(QtWidgets.QWidget): hideKeyboard = Signal() def __init__(self, parent=None): super(VirtualKeyboard, self).__init__(parent) # Load the widgets UI file: self.filename = os.path.join(PATH.SHAREDIR,'widgets_ui', 'virtual_keyboard.ui') try: self.instance = uic.loadUi(self.filename, self) except AttributeError as e: LOG.critical(e) self.NO_ORD_KEY_LIST = list() self.NO_ORD_KEY_LIST.append(Qt.Key_Backspace) self.NO_ORD_KEY_LIST.append(Qt.Key_Enter) self.NO_ORD_KEY_LIST.append(Qt.Key_Escape) self.NO_ORD_KEY_LIST.append(Qt.Key_Delete) self.NO_ORD_KEY_LIST.append(Qt.Key_F1) self.NO_ORD_KEY_LIST.append(Qt.Key_F2) self.NO_ORD_KEY_LIST.append(Qt.Key_F3) self.NO_ORD_KEY_LIST.append(Qt.Key_F4) self.NO_ORD_KEY_LIST.append(Qt.Key_F5) self.NO_ORD_KEY_LIST.append(Qt.Key_F6) self.NO_ORD_KEY_LIST.append(Qt.Key_F7) self.NO_ORD_KEY_LIST.append(Qt.Key_F8) self.NO_ORD_KEY_LIST.append(Qt.Key_F9) self.NO_ORD_KEY_LIST.append(Qt.Key_F10) self.NO_ORD_KEY_LIST.append(Qt.Key_F11) self.NO_ORD_KEY_LIST.append(Qt.Key_F12) self.letter_list = "abcdefghijklmnopqrstuvwxyz" self.number_list = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'minus', 'equal'] self.shift_number = [')', '!', '@', '#', '$', '%', '^', '&&', '*', '('] self.special_list = { 'less': Qt.Key_Less, 'greater': Qt.Key_Greater, 'question': Qt.Key_Question, 'colon': Qt.Key_Colon, 'leftbrace': Qt.Key_BraceLeft, 'rightbrace': Qt.Key_BraceRight, 'doublequote': Qt.Key_QuoteDbl, 'pipe': Qt.Key_Bar, 'underscore': Qt.Key_Underscore, 'plus': Qt.Key_Plus, 'exclamation': Qt.Key_Exclam, 'at': Qt.Key_At, 'pound': Qt.Key_NumberSign, 'dollar': Qt.Key_Dollar, 'percent': Qt.Key_Percent, 'carat': Qt.Key_AsciiCircum, 'ampersand': Qt.Key_Ampersand, 'asterisk': Qt.Key_Asterisk, 'leftparenth': Qt.Key_ParenLeft, 'rightparenth': Qt.Key_ParenRight, 'space': Qt.Key_Space } self.function_keys = { '0': Qt.Key_F10, '1': Qt.Key_F1, '2': Qt.Key_F2, '3': Qt.Key_F3, '4': Qt.Key_F4, '5': Qt.Key_F5, '6': Qt.Key_F6, '7': Qt.Key_F7, '8': Qt.Key_F8, '9': Qt.Key_F9, 'minus': Qt.Key_F11, 'equal': Qt.Key_F12 } self.init_letters() self.init_numbers() self.init_special() # control button group self.btn_back.KEY_CHAR = Qt.Key_Backspace self.btn_delete.KEY_CHAR = Qt.Key_Delete self.btn_enter.KEY_CHAR = Qt.Key_Enter self.letters_buttonGroup.buttonClicked.connect(self.letter_clicked) self.numbers_buttonGroup.buttonClicked.connect(self.special_clicked) self.special_buttonGroup.buttonClicked.connect(self.special_clicked) self.control_buttonGroup.buttonClicked.connect(self.button_clicked) self.btn_hide.clicked.connect(lambda: self.hideKeyboard.emit()) def init_letters(self): for val in self.letter_list: self['btn_' + val].setText(val) self['btn_' + val].KEY_CHAR = ord(val) def init_numbers(self): for i, val in enumerate(self.number_list[:-2]): self['btn_' + val].setText(self.shift_number[i] + '\n' + val) self['btn_' + val].KEY_CHAR = ord(val) self.btn_minus.setText('_\n-') self.btn_minus.KEY_CHAR = Qt.Key_Minus self.btn_equal.setText('+\n=') self.btn_equal.KEY_CHAR = Qt.Key_Equal def init_special(self): self.btn_comma.KEY_CHAR = Qt.Key_Comma self.btn_period.KEY_CHAR = Qt.Key_Period self.btn_semicolon.KEY_CHAR = Qt.Key_Semicolon self.btn_slash.KEY_CHAR = Qt.Key_Slash self.btn_backslash.KEY_CHAR = Qt.Key_Backslash self.btn_apostrophe.KEY_CHAR = Qt.Key_Apostrophe self.btn_left_bracket.KEY_CHAR = Qt.Key_BracketLeft self.btn_right_bracket.KEY_CHAR = Qt.Key_BracketRight self.btn_space.KEY_CHAR = Qt.Key_Space def letter_clicked(self, btn): if self.btn_shift.isChecked(): btn.KEY_CHAR = ord(btn.text().upper()) self.button_clicked(btn) btn.KEY_CHAR = ord(btn.text()) def special_clicked(self, btn): key_save = btn.KEY_CHAR if self.btn_shift.isChecked() and not self.btn_function.isChecked(): key = btn.property('upper') btn.KEY_CHAR = self.special_list.get(key) self.button_clicked(btn) btn.KEY_CHAR = key_save def button_clicked(self, btn): fw = QtWidgets.QApplication.focusWidget() if fw is None: return if btn.KEY_CHAR in self.NO_ORD_KEY_LIST: keyPress = QtGui.QKeyEvent(QEvent.KeyPress, btn.KEY_CHAR, Qt.NoModifier, '') else: if self.btn_shift.isChecked(): modifier = Qt.ShiftModifier self.btn_shift.setChecked(False) else: modifier = Qt.NoModifier keyPress = QtGui.QKeyEvent(QEvent.KeyPress, btn.KEY_CHAR, modifier, chr(btn.KEY_CHAR)) try: QtWidgets.QApplication.sendEvent(fw, keyPress) except: pass def caps_lock_clicked(self, state): if state: for val in self.letter_list: self['btn_' + val].setText(val.upper()) self['btn_' + val].KEY_CHAR = ord(val.upper()) else: self.init_letters() def function_clicked(self, state): if state: for val in self.number_list: alt_txt = self['btn_' + val].property('fcode') self['btn_' + val].setText(alt_txt) for key, val in list(self.function_keys.items()): self['btn_' + key].KEY_CHAR = val else: self.init_numbers() def __getitem__(self, item): return getattr(self, item) def __setitem__(self, item, value): return setattr(self, item, value) ############################# # Testing # ############################# if __name__ == "__main__": from qtpy.QtWidgets import * from qtpy.QtCore import * from qtpy.QtGui import * app = QtWidgets.QApplication(sys.argv) w = VirtualKeyboard() w.show() sys.exit( app.exec() )