From 40820576d76f5b81ebb813b16e90f57b89aa00b0 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Wed, 21 Nov 2018 18:20:01 -0500 Subject: [PATCH] Support for InputText focus set and get. Default text works correctly now, Frame styles for Text Elements (sunken, etc), DEMO touch keyboard --- .../Demo Programs/Qt_Demo_Touch_Keyboard.py | 98 +++++++++++++++++++ PySimpleGUIQt/PySimpleGUIQt.py | 58 ++++++++--- 2 files changed, 143 insertions(+), 13 deletions(-) create mode 100644 PySimpleGUIQt/Demo Programs/Qt_Demo_Touch_Keyboard.py diff --git a/PySimpleGUIQt/Demo Programs/Qt_Demo_Touch_Keyboard.py b/PySimpleGUIQt/Demo Programs/Qt_Demo_Touch_Keyboard.py new file mode 100644 index 00000000..95bd3b98 --- /dev/null +++ b/PySimpleGUIQt/Demo Programs/Qt_Demo_Touch_Keyboard.py @@ -0,0 +1,98 @@ +import PySimpleGUIQt as sg + + +class keyboard(): + def __init__(self, font=('Arial', 16)): + self.font = font + numberRow = '1234567890' + topRow = 'QWERTYUIOP' + midRow = 'ASDFGHJKL' + bottomRow = 'ZXCVBNM' + keyboard_layout = [[sg.Button(c, key=c, pad=(0, 0), size=(4, 2), font=self.font) for c in numberRow] + [ + sg.Button('⌫', key='back', pad=(0, 0), size=(4, 2), font=self.font), + sg.Button('Esc', key='close', pad=(0, 0), size=(4, 2), font=self.font)], + [sg.T(' ' * 4)] + [sg.Button(c, key=c, pad=(0, 0), size=(4, 2), font=self.font) for c in + topRow] + [sg.Stretch()], + [sg.T(' ' * 11)] + [sg.Button(c, key=c, pad=(0, 0), size=(4, 2), font=self.font) for c in + midRow] + [sg.Stretch()], + [sg.T(' ' * 18)] + [sg.Button(c, key=c, pad=(0, 0), size=(4, 2), font=self.font) for c in + bottomRow] + [sg.Stretch()]] + + self.window = sg.Window('keyboard', + grab_anywhere=True, + keep_on_top=True, + alpha_channel=0, + location=(850,350), + no_titlebar=True, + ).Layout(keyboard_layout).Finalize() + self.hide() + + + def hide(self): + self.visible = False + self.window.Disappear() + + def show(self): + self.visible = True + self.window.Reappear() + + def togglevis(self): + if self.visible: + self.hide() + else: + self.show() + + def update(self, focus): + self.event, _ = self.window.Read(timeout=100) + if focus is not None: + self.focus = focus + if self.event is not None: + if self.event == 'close': + self.hide() + elif len(self.event) == 1: + self.focus.Update(self.focus.Get() + self.event) + elif self.event == 'back': + Text = self.focus.Get() + if len(Text) > 0: + Text = Text[:-1] + self.focus.Update(Text) + + + def close(self): + self.window.Close() + + +class GUI(): + def __init__(self): + layout = [[sg.Text('Enter Text')], + [sg.Input(size=(17, 1), key='input1', do_not_clear=True)], + [sg.InputText(size=(17, 1), key='input2', do_not_clear=True)], + [sg.Button('on-screen keyboard', key='keyboard')], + [sg.Button('close', key='close')]] + + self.mainWindow = sg.Window('On-screen test', + grab_anywhere=True, + no_titlebar=False, + ).Layout(layout).Finalize() + self.keyboard = keyboard() + self.focus = None + + def run(self): + while True: + cur_focus = self.mainWindow.FindElementWithFocus() + if cur_focus is not None: + self.focus = cur_focus + event, values = self.mainWindow.Read(timeout=100, timeout_key='timeout') + if self.focus is not None: + self.keyboard.update(self.focus) + if event == 'keyboard': + self.keyboard.togglevis() + elif event == 'close' or event is None: + break + self.keyboard.close() + self.mainWindow.Close() + + +if __name__ == '__main__': + app = GUI() + app.run() diff --git a/PySimpleGUIQt/PySimpleGUIQt.py b/PySimpleGUIQt/PySimpleGUIQt.py index 6e98d645..0137f047 100644 --- a/PySimpleGUIQt/PySimpleGUIQt.py +++ b/PySimpleGUIQt/PySimpleGUIQt.py @@ -468,6 +468,23 @@ class InputText(Element): font=font, tooltip=tooltip) + class InputTextWidget(QWidget): + def __init__(self, qt_qlineedit, element): + self.QT_QLineEdit = qt_qlineedit + self.Element = element + super().__init__() + + def eventFilter(self, widget, event): + # print(f'Got input text event {event}') + if event.type() == QEvent.FocusIn and widget is self.QT_QLineEdit: + self.Element.ParentForm.FocusElement = self.Element + return QWidget.eventFilter(self, widget, event) + + + def QtCallbackFocusInEvent(self,value): + print('Got focus!') + + def QtCallbackTextChanged(self, value): if not self.ChangeSubmits: return @@ -483,7 +500,7 @@ class InputText(Element): elif disabled is False: self.QT_QLineEdit.setDisabled(False) if value is not None: - self.QT_QLineEdit.setText(value) + self.QT_QLineEdit.setText(str(value)) self.DefaultText = value def Get(self): @@ -491,10 +508,7 @@ class InputText(Element): # return self.TKStringVar.get() def SetFocus(self): - try: - self.TKEntry.focus_set() - except: - pass + self.QT_QLineEdit.setFocus() def __del__(self): super().__del__() @@ -1090,6 +1104,10 @@ class Text(Element): text_color=self.TextColor, pad=pad, key=key, tooltip=tooltip) return + def QtCallbackTextClicked(self): + if not self.ClickSubmits: + return + element_callback_quit_mainloop(self) @@ -2904,6 +2922,7 @@ class Window: return element def FindElementWithFocus(self): + return self.FocusElement element = _FindElementWithFocusInSubForm(self) return element @@ -3750,8 +3769,8 @@ def _FindElementWithFocusInSubForm(form): if matching_elem is not None: return matching_elem if element.Type == ELEM_TYPE_INPUT_TEXT: - if element.TKEntry is not None: - if element.TKEntry is element.TKEntry.focus_get(): + if element.QT_QLineEdit is not None: + if element.QT_QLineEdit is element.TKEntry.focus_get(): return element @@ -3867,15 +3886,13 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): qt_row_layout.addWidget(column_widget) # ------------------------- TEXT element ------------------------- # elif element_type == ELEM_TYPE_TEXT: - element.QT_Label = QLabel(element.DisplayText, toplevel_win.QTWindow) - + element.QT_Label = qlabel = QLabel(element.DisplayText, toplevel_win.QTWindow) if element.Justification is not None: justification = element.Justification elif toplevel_win.TextJustification is not None: justification = toplevel_win.TextJustification else: justification = DEFAULT_TEXT_JUSTIFICATION - if justification[0] == 'c': element.QT_Label.setAlignment(Qt.AlignCenter) elif justification[0] == 'r': @@ -3896,6 +3913,17 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): style += 'background-color: %s;' % element.BackgroundColor element.QT_Label.setStyleSheet(style) + if element.ClickSubmits: + qlabel.linkActivated.connect(element.QtCallbackTextClicked) + + if element.Relief is not None: + if element.Relief in (RELIEF_RIDGE, RELIEF_RAISED): + qlabel.setFrameStyle(QFrame.Panel | QFrame.Raised) + elif element.Relief in (RELIEF_SUNKEN, RELIEF_GROOVE): + qlabel.setFrameStyle(QFrame.Panel | QFrame.Sunken) + elif element.Relief == RELIEF_FLAT: + qlabel.setFrameStyle(QFrame.Panel | QFrame.NoFrame) + if element.Tooltip: element.QT_Label.setToolTip(element.Tooltip) # element.QT_Label.setMargin(full_element_pad[0]) @@ -3941,14 +3969,14 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): # ------------------------- INPUT (Single Line) element ------------------------- # elif element_type == ELEM_TYPE_INPUT_TEXT: default_text = element.DefaultText - element.QT_QLineEdit = QLineEdit() + element.QT_QLineEdit = qlineedit = QLineEdit() if element.Justification[0] == 'c': element.QT_QLineEdit.setAlignment(Qt.AlignCenter) elif element.Justification[0] == 'r': element.QT_QLineEdit.setAlignment(Qt.AlignRight) - element.QT_QLineEdit.setPlaceholderText(default_text) + element.QT_QLineEdit.setText(default_text) style = '' if font is not None: style += 'font-family: %s;'%font[0] @@ -3960,7 +3988,7 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): element.QT_QLineEdit.setStyleSheet(style) - if element.AutoSizeText is False or toplevel_win.AutoSizeButtons is False or element.Size[0] is not None: + if element.AutoSizeText is False or toplevel_win.AutoSizeText is False or element.Size[0] is not None: if element_size[0] is not None: element.QT_QLineEdit.setFixedWidth(element_size[0]) if element_size[1] is not None: @@ -3975,6 +4003,10 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): element.QT_QLineEdit.returnPressed.connect(element.QtCallbackReturnPressed) + element.InputTextWidget = Input.InputTextWidget(element.QT_QLineEdit, element) + element.QT_QLineEdit.installEventFilter(element.InputTextWidget) + + # element.QT_QLineEdit.focusInEvent.connect(element.QtCallbackFocusInEvent) qt_row_layout.setContentsMargins(*full_element_pad) qt_row_layout.addWidget(element.QT_QLineEdit)