From bfc9a050d2a6c0034649524a3001cf348297129c Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Fri, 30 Nov 2018 13:46:22 -0500 Subject: [PATCH 01/12] MULTIWINDOW support copied over from Qt to stop accidental None returns, new Input Update parm - select, --- PySimpleGUI.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 520ae408..be46a905 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -506,7 +506,7 @@ class InputText(Element): super().__init__(ELEM_TYPE_INPUT_TEXT, size=size, background_color=bg, text_color=fg, key=key, pad=pad, font=font, tooltip=tooltip) - def Update(self, value=None, disabled=None): + def Update(self, value=None, disabled=None, select=None): if disabled is True: self.TKEntry['state'] = 'disabled' elif disabled is False: @@ -517,6 +517,9 @@ class InputText(Element): except: pass self.DefaultText = value + if select: + self.TKEntry.select_range(0, 'end') + def Get(self): try: @@ -2966,6 +2969,7 @@ class Window: self.DisableClose = disable_close self._Hidden = False self._Size = size + self.XFound = False # ------------------------- Add ONE Row to Form ------------------------- # def AddRow(self, *args): @@ -3124,7 +3128,7 @@ class Window: # print("** REALTIME PROBLEM FOUND **", results) if self.RootNeedsDestroying: - # print('*** DESTROYING really late***') + print('*** DESTROYING really late***') self.TKroot.destroy() # _my_windows.Decrement() self.LastButtonClicked = None @@ -3165,6 +3169,12 @@ class Window: self.LastButtonClicked = None return results else: + if not self.XFound and self.Timeout != 0 and self.Timeout is not None and self.ReturnValues[ + 0] is None: # Special Qt case because returning for no reason so fake timeout + self.ReturnValues = self.TimeoutKey, self.ReturnValues[1] # fake a timeout + elif not self.XFound and self.ReturnValues[0] is None: # TODO HIGHLY EXPERIMENTAL... added due to tray icon interaction + # print("*** Faking timeout ***") + self.ReturnValues = self.TimeoutKey, self.ReturnValues[1] # fake a timeout return self.ReturnValues def ReadNonBlocking(self): @@ -3345,6 +3355,7 @@ class Window: # print('Got closing callback', self.DisableClose) if self.DisableClose: return + self.XFound = True if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit! self.TKroot.quit() # kick the users out of the mainloop self.TKroot.destroy() # kick the users out of the mainloop From e9b357eb35e3dba7e42e5aef00faa10e7db22296 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Fri, 30 Nov 2018 13:46:47 -0500 Subject: [PATCH 02/12] Doc update --- docs/index.md | 5 +++-- readme.md | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/index.md b/docs/index.md index b134cf9b..6dca10fb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,6 +10,7 @@ [![Downloads](http://pepy.tech/badge/pysimplegui)](http://pepy.tech/project/pysimplegui) [![Downloads ](https://pepy.tech/badge/pysimplegui27)](https://pepy.tech/project/pysimplegui27) +[![Downloads](https://pepy.tech/badge/pysimpleguiqt)](https://pepy.tech/project/pysimpleguiqt) ![Documentation Status](https://readthedocs.org/projects/pysimplegui/badge/?version=latest) ![Awesome Meter](https://img.shields.io/badge/Awesome_meter-100-yellow.svg) ![Python Version](https://img.shields.io/badge/Python-2.7_3.x-yellow.svg) @@ -33,7 +34,7 @@ ![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.16.0-blue.svg?longCache=true&style=for-the-badge) -![Python Version](https://img.shields.io/badge/PySimpleGUIQt_For_Python_3.x_Version-01.17.0-orange.svg?longCache=true&style=for-the-badge) +![Python Version](https://img.shields.io/badge/PySimpleGUIQt_For_Python_3.x_Version-0.19.0-orange.svg?longCache=true&style=for-the-badge) [Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142) @@ -3937,7 +3938,7 @@ From the start of the PSG project, tkinter was not meant to be the only underlyi ## Author -MikeTheWatchGuy +MikeB ## Demo Code Contributors diff --git a/readme.md b/readme.md index b134cf9b..6dca10fb 100644 --- a/readme.md +++ b/readme.md @@ -10,6 +10,7 @@ [![Downloads](http://pepy.tech/badge/pysimplegui)](http://pepy.tech/project/pysimplegui) [![Downloads ](https://pepy.tech/badge/pysimplegui27)](https://pepy.tech/project/pysimplegui27) +[![Downloads](https://pepy.tech/badge/pysimpleguiqt)](https://pepy.tech/project/pysimpleguiqt) ![Documentation Status](https://readthedocs.org/projects/pysimplegui/badge/?version=latest) ![Awesome Meter](https://img.shields.io/badge/Awesome_meter-100-yellow.svg) ![Python Version](https://img.shields.io/badge/Python-2.7_3.x-yellow.svg) @@ -33,7 +34,7 @@ ![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.16.0-blue.svg?longCache=true&style=for-the-badge) -![Python Version](https://img.shields.io/badge/PySimpleGUIQt_For_Python_3.x_Version-01.17.0-orange.svg?longCache=true&style=for-the-badge) +![Python Version](https://img.shields.io/badge/PySimpleGUIQt_For_Python_3.x_Version-0.19.0-orange.svg?longCache=true&style=for-the-badge) [Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142) @@ -3937,7 +3938,7 @@ From the start of the PSG project, tkinter was not meant to be the only underlyi ## Author -MikeTheWatchGuy +MikeB ## Demo Code Contributors From a04babb4792a7f6b982b8bf77fc0450249c4d0c4 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Fri, 30 Nov 2018 14:00:12 -0500 Subject: [PATCH 03/12] New Floating Window demo - auto complete of input field --- DemoPrograms/Demo_Input_Auto_Complete.py | 95 ++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 DemoPrograms/Demo_Input_Auto_Complete.py diff --git a/DemoPrograms/Demo_Input_Auto_Complete.py b/DemoPrograms/Demo_Input_Auto_Complete.py new file mode 100644 index 00000000..0c598671 --- /dev/null +++ b/DemoPrograms/Demo_Input_Auto_Complete.py @@ -0,0 +1,95 @@ +import sys +import re +if sys.version_info[0] >= 3: + import PySimpleGUI as sg +else: + import PySimpleGUI27 as sg + + + + +def autocomplete_popup_show(text_list ): + autocomplete_popup_layout = [[sg.Listbox(values=text_list, + size=(15,len(text_list)), + change_submits=True, + bind_return_key=True, + auto_size_text=True, + key='_FLOATING_LISTBOX_', enable_events=True)]] + + autocomplete_popup = sg.Window("Borderless Window", + default_element_size=(12, 1), + text_justification='c', + auto_size_text=False, + auto_size_buttons=False, + no_titlebar=True, + grab_anywhere=True, + return_keyboard_events=True, + keep_on_top=True, + background_color='black', + location=(1320,622), + default_button_element_size=(12, 1)) + + window = autocomplete_popup.Layout(autocomplete_popup_layout).Finalize() + return window + + + +def predict_text(input, lista): + pattern = re.compile('.*' + input + '.*') + return [w for w in lista if re.match(pattern, w)] + +# print(predict_text('1', ['123'])) +choices = ['ABC' + str(i) for i in range(30)] +# print(predict_text('1', values)) +# print(values) +layout = [ [sg.Text('Your typed chars appear here:')], + [sg.In(key='_INPUT_', size=(10,1), do_not_clear=True),sg.Text('', key='_OUTPUT_')], + [sg.Button('Show'), sg.Button('Exit')], + ] + +window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout) + + +sel_item = -1 +while True: # Event Loop + event, values = window.Read(timeout=1000) + if event is None or event == 'Exit': + break + if event != sg.TIMEOUT_KEY: + in_val = values['_INPUT_'] + prediction_list = predict_text(str(in_val), choices) + if prediction_list: + try: + fwindow.Close() + except: pass + fwindow = autocomplete_popup_show(prediction_list) + list_elem = fwindow.Element('_FLOATING_LISTBOX_') + + window.Element('_OUTPUT_').Update(prediction_list[0]) + + if event == '_COMBO_': + sg.Popup('Chose', values['_COMBO_']) + if event == 'Down:40': + sel_item = sel_item + (sel_item0) + list_elem.Update(set_to_index=sel_item) + if event == '\r' or event == 'Show': + chosen = vals2['_FLOATING_LISTBOX_'] + window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'], select=True) + fwindow.Close() + sel_item = -1 + if event == 'Escape:27': + window.Element('_INPUT_').Update('') + + try: + ev2, vals2 = fwindow.Read(timeout=10) + if ev2 != sg.TIMEOUT_KEY: + fwindow.Close() + # sg.Popup('Chose from window', vals2['_FLOATING_LISTBOX_']) + window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'], select=True) + sel_item = -1 + + except: pass +window.Close() From 15a4db94db879d3df0389f43a1f9246862872071 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Fri, 30 Nov 2018 14:04:05 -0500 Subject: [PATCH 04/12] Removed first window timeout --- DemoPrograms/Demo_Input_Auto_Complete.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DemoPrograms/Demo_Input_Auto_Complete.py b/DemoPrograms/Demo_Input_Auto_Complete.py index 0c598671..fa67c566 100644 --- a/DemoPrograms/Demo_Input_Auto_Complete.py +++ b/DemoPrograms/Demo_Input_Auto_Complete.py @@ -52,7 +52,7 @@ window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout) sel_item = -1 while True: # Event Loop - event, values = window.Read(timeout=1000) + event, values = window.Read() if event is None or event == 'Exit': break if event != sg.TIMEOUT_KEY: @@ -84,7 +84,7 @@ while True: # Event Loop window.Element('_INPUT_').Update('') try: - ev2, vals2 = fwindow.Read(timeout=10) + ev2, vals2 = fwindow.Read(timeout=0) if ev2 != sg.TIMEOUT_KEY: fwindow.Close() # sg.Popup('Chose from window', vals2['_FLOATING_LISTBOX_']) From 5dc2eb3cb003daeb70bdcb0ae8c5a65d260d419e Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Dec 2018 14:00:39 -0500 Subject: [PATCH 05/12] Change to timeouts seems to fix the problems --- DemoPrograms/Demo_Input_Auto_Complete.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DemoPrograms/Demo_Input_Auto_Complete.py b/DemoPrograms/Demo_Input_Auto_Complete.py index fa67c566..db95b0b1 100644 --- a/DemoPrograms/Demo_Input_Auto_Complete.py +++ b/DemoPrograms/Demo_Input_Auto_Complete.py @@ -52,7 +52,7 @@ window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout) sel_item = -1 while True: # Event Loop - event, values = window.Read() + event, values = window.Read(timeout=0) if event is None or event == 'Exit': break if event != sg.TIMEOUT_KEY: @@ -84,7 +84,7 @@ while True: # Event Loop window.Element('_INPUT_').Update('') try: - ev2, vals2 = fwindow.Read(timeout=0) + ev2, vals2 = fwindow.Read(timeout=100) if ev2 != sg.TIMEOUT_KEY: fwindow.Close() # sg.Popup('Chose from window', vals2['_FLOATING_LISTBOX_']) From 6270a05eea0cf2624349ccd57e4e0724dbd54b5c Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Dec 2018 14:37:35 -0500 Subject: [PATCH 06/12] Checking for keys in a more portable way. --- DemoPrograms/Demo_Input_Auto_Complete.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/DemoPrograms/Demo_Input_Auto_Complete.py b/DemoPrograms/Demo_Input_Auto_Complete.py index db95b0b1..04a0c436 100644 --- a/DemoPrograms/Demo_Input_Auto_Complete.py +++ b/DemoPrograms/Demo_Input_Auto_Complete.py @@ -69,10 +69,10 @@ while True: # Event Loop if event == '_COMBO_': sg.Popup('Chose', values['_COMBO_']) - if event == 'Down:40': + if event.startswith('Down'): sel_item = sel_item + (sel_item0) list_elem.Update(set_to_index=sel_item) if event == '\r' or event == 'Show': @@ -80,14 +80,13 @@ while True: # Event Loop window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'], select=True) fwindow.Close() sel_item = -1 - if event == 'Escape:27': + if event.startswith('Escape'): window.Element('_INPUT_').Update('') try: - ev2, vals2 = fwindow.Read(timeout=100) + ev2, vals2 = fwindow.Read(timeout=10) if ev2 != sg.TIMEOUT_KEY: fwindow.Close() - # sg.Popup('Chose from window', vals2['_FLOATING_LISTBOX_']) window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'], select=True) sel_item = -1 From ce5c7eabf61cd93b0dbaee131b6efcac5861c4bc Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Dec 2018 15:24:12 -0500 Subject: [PATCH 07/12] Made portable between tkinter and Qt --- DemoPrograms/Demo_Input_Auto_Complete.py | 30 +++++++++++++++--------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/DemoPrograms/Demo_Input_Auto_Complete.py b/DemoPrograms/Demo_Input_Auto_Complete.py index 04a0c436..aed702fc 100644 --- a/DemoPrograms/Demo_Input_Auto_Complete.py +++ b/DemoPrograms/Demo_Input_Auto_Complete.py @@ -1,16 +1,17 @@ import sys import re -if sys.version_info[0] >= 3: - import PySimpleGUI as sg -else: - import PySimpleGUI27 as sg +QT = False +if QT: + import PySimpleGUIQt as sg +else: + import PySimpleGUI as sg def autocomplete_popup_show(text_list ): autocomplete_popup_layout = [[sg.Listbox(values=text_list, - size=(15,len(text_list)), + size=(100,20*len(text_list)) if QT else (15, len(text_list)), change_submits=True, bind_return_key=True, auto_size_text=True, @@ -51,6 +52,7 @@ window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout) sel_item = -1 +skip_event = False while True: # Event Loop event, values = window.Read(timeout=0) if event is None or event == 'Exit': @@ -69,26 +71,32 @@ while True: # Event Loop if event == '_COMBO_': sg.Popup('Chose', values['_COMBO_']) - if event.startswith('Down'): + if event.startswith('Down') or event.startswith('special 16777237'): sel_item = sel_item + (sel_item0) list_elem.Update(set_to_index=sel_item) + skip_event = True if event == '\r' or event == 'Show': chosen = vals2['_FLOATING_LISTBOX_'] window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'], select=True) fwindow.Close() sel_item = -1 - if event.startswith('Escape'): + if event.startswith('Escape') or event.startswith('special 16777216'): window.Element('_INPUT_').Update('') try: ev2, vals2 = fwindow.Read(timeout=10) - if ev2 != sg.TIMEOUT_KEY: + if ev2 == '_FLOATING_LISTBOX_' and skip_event and QT: + skip_event = False + elif ev2 != sg.TIMEOUT_KEY and ev2 is not None: + print(f'Event2 = {ev2}') fwindow.Close() - window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'], select=True) + window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'][0], select=True) sel_item = -1 - + fwindow = None except: pass window.Close() From 153c9a1b924d8257395cead6a679ad1ebbace786 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Dec 2018 15:25:06 -0500 Subject: [PATCH 08/12] Added Listbox.Update(set_to_index) and Input.Update(select) --- PySimpleGUIQt/PySimpleGUIQt.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/PySimpleGUIQt/PySimpleGUIQt.py b/PySimpleGUIQt/PySimpleGUIQt.py index 244a5d0b..06f78457 100644 --- a/PySimpleGUIQt/PySimpleGUIQt.py +++ b/PySimpleGUIQt/PySimpleGUIQt.py @@ -539,7 +539,7 @@ class InputText(Element): self.ReturnKeyHandler(None) return - def Update(self, value=None, disabled=None): + def Update(self, value=None, disabled=None, select=None): if disabled is True: self.QT_QLineEdit.setDisabled(True) elif disabled is False: @@ -547,6 +547,8 @@ class InputText(Element): if value is not None: self.QT_QLineEdit.setText(str(value)) self.DefaultText = value + if select: + self.QT_QLineEdit.setSelection() def Get(self): return self.QT_QLineEdit.text() @@ -754,7 +756,7 @@ class Listbox(Element): element_callback_quit_mainloop(self) - def Update(self, values=None, disabled=None): + def Update(self, values=None, disabled=None, set_to_index=None): if values is not None: self.Values = values for i in range(self.QT_ListWidget.count()): @@ -764,6 +766,9 @@ class Listbox(Element): self.QT_ListWidget.setDisabled(True) elif disabled == False: self.QT_ListWidget.setDisabled(False) + if set_to_index is not None: + self.QT_ListWidget.setCurrentRow(set_to_index) + return def SetValue(self, values): From a37583fb06b9aec35ad214d5fbff5ae7d458ce19 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Dec 2018 15:49:39 -0500 Subject: [PATCH 09/12] Another timeout change, make show button do nothing except refresh --- DemoPrograms/Demo_Input_Auto_Complete.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DemoPrograms/Demo_Input_Auto_Complete.py b/DemoPrograms/Demo_Input_Auto_Complete.py index aed702fc..96174780 100644 --- a/DemoPrograms/Demo_Input_Auto_Complete.py +++ b/DemoPrograms/Demo_Input_Auto_Complete.py @@ -54,7 +54,7 @@ window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout) sel_item = -1 skip_event = False while True: # Event Loop - event, values = window.Read(timeout=0) + event, values = window.Read(timeout=500) if event is None or event == 'Exit': break if event != sg.TIMEOUT_KEY: @@ -80,7 +80,7 @@ while True: # Event Loop sel_item = sel_item - (sel_item>0) list_elem.Update(set_to_index=sel_item) skip_event = True - if event == '\r' or event == 'Show': + if event == '\r': chosen = vals2['_FLOATING_LISTBOX_'] window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'], select=True) fwindow.Close() From 7e8e120fa1d5adc0392b47d8179c67bd8472a7a0 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Dec 2018 15:58:41 -0500 Subject: [PATCH 10/12] Cleaned up code --- DemoPrograms/Demo_Input_Auto_Complete.py | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/DemoPrograms/Demo_Input_Auto_Complete.py b/DemoPrograms/Demo_Input_Auto_Complete.py index 96174780..8ad3738d 100644 --- a/DemoPrograms/Demo_Input_Auto_Complete.py +++ b/DemoPrograms/Demo_Input_Auto_Complete.py @@ -1,14 +1,11 @@ import sys import re - QT = False if QT: import PySimpleGUIQt as sg else: import PySimpleGUI as sg - - def autocomplete_popup_show(text_list ): autocomplete_popup_layout = [[sg.Listbox(values=text_list, size=(100,20*len(text_list)) if QT else (15, len(text_list)), @@ -19,7 +16,6 @@ def autocomplete_popup_show(text_list ): autocomplete_popup = sg.Window("Borderless Window", default_element_size=(12, 1), - text_justification='c', auto_size_text=False, auto_size_buttons=False, no_titlebar=True, @@ -34,23 +30,18 @@ def autocomplete_popup_show(text_list ): return window - def predict_text(input, lista): pattern = re.compile('.*' + input + '.*') return [w for w in lista if re.match(pattern, w)] -# print(predict_text('1', ['123'])) -choices = ['ABC' + str(i) for i in range(30)] -# print(predict_text('1', values)) -# print(values) +choices = ['ABC' + str(i) for i in range(30)] # dummy data + layout = [ [sg.Text('Your typed chars appear here:')], - [sg.In(key='_INPUT_', size=(10,1), do_not_clear=True),sg.Text('', key='_OUTPUT_')], - [sg.Button('Show'), sg.Button('Exit')], - ] + [sg.In(key='_INPUT_', size=(10,1), do_not_clear=True)], + [sg.Button('Show'), sg.Button('Exit')],] window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout) - sel_item = -1 skip_event = False while True: # Event Loop @@ -66,14 +57,10 @@ while True: # Event Loop except: pass fwindow = autocomplete_popup_show(prediction_list) list_elem = fwindow.Element('_FLOATING_LISTBOX_') - - window.Element('_OUTPUT_').Update(prediction_list[0]) - if event == '_COMBO_': sg.Popup('Chose', values['_COMBO_']) if event.startswith('Down') or event.startswith('special 16777237'): sel_item = sel_item + (sel_item Date: Sat, 1 Dec 2018 16:05:40 -0500 Subject: [PATCH 11/12] Set Selection support in Input.Update. Detecting ENTER key in auto complete demo --- DemoPrograms/Demo_Input_Auto_Complete.py | 8 +++++--- PySimpleGUIQt/PySimpleGUIQt.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/DemoPrograms/Demo_Input_Auto_Complete.py b/DemoPrograms/Demo_Input_Auto_Complete.py index 8ad3738d..e963dad0 100644 --- a/DemoPrograms/Demo_Input_Auto_Complete.py +++ b/DemoPrograms/Demo_Input_Auto_Complete.py @@ -1,6 +1,6 @@ import sys import re -QT = False +QT = True if QT: import PySimpleGUIQt as sg else: @@ -49,6 +49,7 @@ while True: # Event Loop if event is None or event == 'Exit': break if event != sg.TIMEOUT_KEY: + # print(f'ev1 {event}') in_val = values['_INPUT_'] prediction_list = predict_text(str(in_val), choices) if prediction_list: @@ -67,9 +68,9 @@ while True: # Event Loop sel_item = sel_item - (sel_item>0) list_elem.Update(set_to_index=sel_item) skip_event = True - if event == '\r': + if event == '\r' or event.startswith('special 16777220'): chosen = vals2['_FLOATING_LISTBOX_'] - window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'], select=True) + window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'][0], select=True) fwindow.Close() sel_item = -1 if event.startswith('Escape') or event.startswith('special 16777216'): @@ -80,6 +81,7 @@ while True: # Event Loop if ev2 == '_FLOATING_LISTBOX_' and skip_event and QT: skip_event = False elif ev2 != sg.TIMEOUT_KEY and ev2 is not None: + # print(f'ev2 {ev2}') fwindow.Close() window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'][0], select=True) sel_item = -1 diff --git a/PySimpleGUIQt/PySimpleGUIQt.py b/PySimpleGUIQt/PySimpleGUIQt.py index 06f78457..4fa25ac8 100644 --- a/PySimpleGUIQt/PySimpleGUIQt.py +++ b/PySimpleGUIQt/PySimpleGUIQt.py @@ -548,7 +548,7 @@ class InputText(Element): self.QT_QLineEdit.setText(str(value)) self.DefaultText = value if select: - self.QT_QLineEdit.setSelection() + self.QT_QLineEdit.setSelection(0,QtGui.QTextCursor.End ) def Get(self): return self.QT_QLineEdit.text() From 579377e748e80cca3964dcd450e7873343450750 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Dec 2018 16:44:25 -0500 Subject: [PATCH 12/12] readonly/editable support for Combobox. Autocomplete feature for Qt Combobox --- PySimpleGUIQt/PySimpleGUIQt.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/PySimpleGUIQt/PySimpleGUIQt.py b/PySimpleGUIQt/PySimpleGUIQt.py index 4fa25ac8..a33709b9 100644 --- a/PySimpleGUIQt/PySimpleGUIQt.py +++ b/PySimpleGUIQt/PySimpleGUIQt.py @@ -573,7 +573,7 @@ Input = InputText class Combo(Element): def __init__(self, values, default_value=None, size=(None, None), auto_size_text=None, background_color=None, text_color=None, change_submits=False, enable_events=False, disabled=False, key=None, pad=None, tooltip=None, - readonly=False, visible_items=10, font=None): + readonly=False, visible_items=10, font=None, auto_complete=True): ''' Input Combo Box Element (also called Dropdown box) :param values: @@ -591,6 +591,7 @@ class Combo(Element): bg = background_color if background_color else DEFAULT_INPUT_ELEMENTS_COLOR fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR self.VisibleItems = visible_items + self.AutoComplete = auto_complete super().__init__(ELEM_TYPE_INPUT_COMBO, size=size, auto_size_text=auto_size_text, background_color=bg, text_color=fg, key=key, pad=pad, tooltip=tooltip, font=font or DEFAULT_FONT) @@ -628,7 +629,6 @@ class Combo(Element): if font is not None: style = create_style_from_font(font) self.QT_ComboBox.setStyleSheet(style) - return def __del__(self): @@ -4483,6 +4483,10 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): element.QT_ComboBox.currentIndexChanged.connect(element.QtCurrentItemChanged) if element.Tooltip: element.QT_ComboBox.setToolTip(element.Tooltip) + if not element.Readonly: + element.QT_ComboBox.setEditable(True) + if not element.AutoComplete: + element.QT_ComboBox.setAutoCompletion(True) qt_row_layout.addWidget(element.QT_ComboBox) # ------------------------- OPTION MENU (Like ComboBox but different) element ------------------------- # elif element_type == ELEM_TYPE_INPUT_OPTION_MENU: