diff --git a/Demo_All_Widgets.py b/Demo_All_Widgets.py new file mode 100644 index 00000000..51d70237 --- /dev/null +++ b/Demo_All_Widgets.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +import sys +if sys.version_info[0] >= 3: + import PySimpleGUI as sg +else: + import PySimpleGUI27 as sg + +sg.ChangeLookAndFeel('GreenTan') + +# ------ Menu Definition ------ # +menu_def = [['&File', ['&Open', '&Save', 'E&xit', 'Properties']], + ['&Edit', ['Paste', ['Special', 'Normal', ], 'Undo'], ], + ['&Help', '&About...'], ] + +# ------ Column Definition ------ # +column1 = [[sg.Text('Column 1', background_color='lightblue', justification='center', size=(10, 1))], + [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')], + [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2')], + [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3')]] + +layout = [ + [sg.Menu(menu_def, tearoff=True)], + [sg.Text('(Almost) All widgets in one Window!', size=(30, 1), justification='center', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)], + [sg.Text('Here is some text.... and a place to enter text')], + [sg.InputText('This is my text')], + [sg.Frame(layout=[ + [sg.Checkbox('Checkbox', size=(10,1)), sg.Checkbox('My second checkbox!', default=True)], + [sg.Radio('My first Radio! ', "RADIO1", default=True, size=(10,1)), sg.Radio('My second Radio!', "RADIO1")]], title='Options',title_color='red', relief=sg.RELIEF_SUNKEN, tooltip='Use these to set flags')], + [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3)), + sg.Multiline(default_text='A second multi-line', size=(35, 3))], + [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 1)), + sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)], + [sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))], + [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)), + sg.Frame('Labelled Group',[[ + sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25, tick_interval=25), + sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75), + sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10), + sg.Column(column1, background_color='lightblue')]])], + [sg.Text('_' * 80)], + [sg.Text('Choose A Folder', size=(35, 1))], + [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'), + sg.InputText('Default Folder'), sg.FolderBrowse()], + [sg.Submit(tooltip='Click to submit this form'), sg.Cancel()]] + +window = sg.Window('Everything bagel', default_element_size=(40, 1), grab_anywhere=False).Layout(layout) +event, values = window.Read() + +sg.Popup('Title', + 'The results of the window.', + 'The button clicked was "{}"'.format(event), + 'The values are', values) + + diff --git a/PySimpleGUI_Qt/Demo_HowDoI.py b/PySimpleGUI_Qt/Demo_HowDoI.py new file mode 100644 index 00000000..56f152d7 --- /dev/null +++ b/PySimpleGUI_Qt/Demo_HowDoI.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +import sys +import PySimpleGUI_Qt as sg +import subprocess + + +# Test this command in a dos window if you are having trouble. +HOW_DO_I_COMMAND = 'python -m howdoi.howdoi' + +# if you want an icon on your taskbar for this gui, then change this line of code to point to the ICO file +DEFAULT_ICON = 'question.ico' + +def HowDoI(): + ''' + Make and show a window (PySimpleGUI form) that takes user input and sends to the HowDoI web oracle + Excellent example of 2 GUI concepts + 1. Output Element that will show text in a scrolled window + 2. Non-Window-Closing Buttons - These buttons will cause the form to return with the form's values, but doesn't close the form + :return: never returns + ''' + # ------- Make a new Window ------- # + sg.ChangeLookAndFeel('GreenTan') # give our form a spiffy set of colors + + layout = [ + [sg.Text('Ask and your answer will appear here....')], + [sg.Output(size=(900, 500), font=('Courier', 10))], + [ sg.Spin(values=(1, 4), initial_value=1, size=(50, 25), key='Num Answers', font=('Helvetica', 15)), + sg.Text('Num Answers',font=('Helvetica', 15), size=(170,22)), sg.Checkbox('Display Full Text', key='full text', font=('Helvetica', 15), size=(200,22)), + sg.T('Command History', font=('Helvetica', 15)), sg.T('', size=(100,25), text_color=sg.BLUES[0], key='history'), sg.Stretch()], + [sg.Multiline(size=(600, 100), enter_submits=True, focus=True, key='query', do_not_clear=False), sg.Stretch(), + sg.ReadButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), + sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0])), sg.Stretch()] + ] + + window = sg.Window('How Do I ??', + default_element_size=(100, 25), + # element_padding=(10,10), + icon=DEFAULT_ICON, + font=('Helvetica',14), + default_button_element_size=(70,50), + return_keyboard_events=True, + no_titlebar=False, + grab_anywhere=True,) + + window.Layout(layout) + # ---===--- Loop taking in user input and using it to query HowDoI --- # + command_history = [] + history_offset = 0 + while True: + event, values = window.Read() + if event == 'SEND' or event == 'query': + # window.FindElement('+OUTPUT+').Update('test of output') # manually clear input because keyboard events blocks clear + + query = values['query'].rstrip() + # print(query) + QueryHowDoI(query, values['Num Answers'], values['full text']) # send the string to HowDoI + command_history.append(query) + history_offset = len(command_history)-1 + window.FindElement('query').Update('') # manually clear input because keyboard events blocks clear + window.FindElement('history').Update('\n'.join(command_history[-3:])) + elif event == None or event == 'EXIT': # if exit button or closed using X + break + elif 'Up' in event and len(command_history): # scroll back in history + command = command_history[history_offset] + history_offset -= 1 * (history_offset > 0) # decrement is not zero + window.FindElement('query').Update(command) + elif 'Down' in event and len(command_history): # scroll forward in history + history_offset += 1 * (history_offset < len(command_history)-1) # increment up to end of list + command = command_history[history_offset] + window.FindElement('query').Update(command) + elif 'Escape' in event: # clear currently line + window.FindElement('query').Update('') + + +def QueryHowDoI(Query, num_answers, full_text): + ''' + Kicks off a subprocess to send the 'Query' to HowDoI + Prints the result, which in this program will route to a gooeyGUI window + :param Query: text english question to ask the HowDoI web engine + :return: nothing + ''' + howdoi_command = HOW_DO_I_COMMAND + full_text_option = ' -a' if full_text else '' + t = subprocess.Popen(howdoi_command + ' \"'+ Query + '\" -n ' + str(num_answers)+full_text_option, stdout=subprocess.PIPE) + (output, err) = t.communicate() + print('{:^88}'.format(Query.rstrip())) + print('_'*60) + print(output.decode("utf-8") ) + exit_code = t.wait() + +if __name__ == '__main__': + HowDoI() + diff --git a/PySimpleGUI_Qt/PySimpleGUI_Qt.py b/PySimpleGUI_Qt/PySimpleGUI_Qt.py index 3421d8fe..f6ad3184 100644 --- a/PySimpleGUI_Qt/PySimpleGUI_Qt.py +++ b/PySimpleGUI_Qt/PySimpleGUI_Qt.py @@ -6,10 +6,10 @@ import textwrap import pickle import calendar from PySide2.QtWidgets import QApplication, QLabel, QWidget, QLineEdit, QComboBox, QFormLayout, QVBoxLayout, QHBoxLayout, QListWidget, QDial -from PySide2.QtWidgets import QSlider, QCheckBox, QRadioButton, QSpinBox, QPushButton, QTextEdit, QMainWindow, QDialog +from PySide2.QtWidgets import QSlider, QCheckBox, QRadioButton, QSpinBox, QPushButton, QTextEdit, QMainWindow, QDialog, QAbstractItemView from PySide2.QtWidgets import QSpacerItem, QFrame, QGroupBox, QTextBrowser, QPlainTextEdit, QButtonGroup, QFileDialog # from PySide2.QtWidgets import -from PySide2.QtCore import Qt,QProcess +from PySide2.QtCore import Qt,QProcess, QEvent import PySide2.QtGui as QtGui import PySide2.QtWidgets as QtWidgets @@ -134,7 +134,7 @@ DEFAULT_SLIDER_BORDER_WIDTH = 1 DEFAULT_SLIDER_RELIEF = 'flat' DEFAULT_FRAME_RELIEF = 'groove' -DEFAULT_LISTBOX_SELECT_MODE = 'single' +DEFAULT_LISTBOX_SELECT_MODE = 'extended' SELECT_MODE_MULTIPLE = 'multiple' LISTBOX_SELECT_MODE_MULTIPLE = 'multiple' SELECT_MODE_BROWSE = 'browse' @@ -143,6 +143,8 @@ SELECT_MODE_EXTENDED = 'extended' LISTBOX_SELECT_MODE_EXTENDED = 'extended' SELECT_MODE_SINGLE = 'single' LISTBOX_SELECT_MODE_SINGLE = 'single' +SELECT_MODE_CONTIGUOUS = 'contiguous' +LISTBOX_SELECT_MODE_CONTIGUOUS = 'contiguous' TABLE_SELECT_MODE_NONE = 'NONE' TABLE_SELECT_MODE_BROWSE = 'BROWSE' @@ -477,7 +479,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, disabled=False, key=None, pad=None, tooltip=None, - readonly=False, font=None): + readonly=False, visible_items=10, font=None): ''' Input Combo Box Element (also called Dropdown box) :param values: @@ -494,6 +496,7 @@ class Combo(Element): self.Readonly = readonly 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 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) @@ -647,6 +650,8 @@ class Listbox(Element): self.SelectMode = SELECT_MODE_MULTIPLE elif select_mode == LISTBOX_SELECT_MODE_SINGLE: self.SelectMode = SELECT_MODE_SINGLE + elif select_mode == LISTBOX_SELECT_MODE_CONTIGUOUS: + self.SelectMode = SELECT_MODE_CONTIGUOUS else: self.SelectMode = DEFAULT_LISTBOX_SELECT_MODE bg = background_color if background_color else DEFAULT_INPUT_ELEMENTS_COLOR @@ -881,10 +886,29 @@ class Multiline(Element, QWidget): text_color=fg, key=key, pad=pad, tooltip=tooltip, font=font or DEFAULT_FONT) return + + class MultiQWidget(QWidget): + def __init__(self, qt_textedit, element): + self.QT_TextEdit = qt_textedit + self.Element = element + super().__init__() + + def eventFilter(self, widget, event): + if self.Element.EnterSubmits and event.type() == QEvent.KeyPress and widget is self.QT_TextEdit: + key = event.key() + if key in (Qt.Key_Return, Qt.Key_Enter): + self.Element.ReturnKeyHandler(0) + # self.Element.ParentForm.LastButtonClicked = self.Element.Key + # self.Element.ParentForm.FormRemainedOpen = True + # if self.Element.ParentForm.CurrentlyRunningMainloop: + # self.Element.ParentForm.QTApplication.exit() + return QWidget.eventFilter(self, widget, event) + + def Update(self, value=None, disabled=None, append=False, font=None): if value is not None: self.DefaultText = value - self.QT_TextEdit.setPlaceholderText(value) + self.QT_TextEdit.setText(value) if self.Autoscroll: pass @@ -901,19 +925,6 @@ class Multiline(Element, QWidget): def SetFocus(self): pass - def eventFilter(self, widget, event): - if (event.type() == Qt.QEvent.KeyPress and - widget is self.QT_TextEdit): - key = event.key() - if key == Qt.Qt.Key_Escape: - print('escape') - else: - if key == Qt.Qt.Key_Return: - self.QT_TextEdit.setText('return') - elif key == Qt.Qt.Key_Enter: - self.QT_TextEdit.setText('enter') - return True - return QtGui.QWidget.eventFilter(self, widget, event) def __del__(self): super().__del__() @@ -1881,16 +1892,7 @@ class Slider(Element): text_color=text_color, key=key, pad=pad, tooltip=tooltip) return - def Qt_init(self): - self.QT_Slider = QSlider() - if self.Orientation.startswith('h'): - self.QT_Slider.setOrientation(Qt.Horizontal) - else: - self.QT_Slider.setOrientation(Qt.Vertical) - self.QT_Slider.setMinimum(self.Range[0]) - self.QT_Slider.setMaximum(self.Range[1]) - self.QT_Slider.setTickPosition(QSlider.TicksBothSides) - self.QT_Slider.setTickInterval(self.Range[1] / 10) + def Update(self, value=None, range=(None, None), disabled=None): if value is not None: @@ -2439,6 +2441,7 @@ class Window: self.QTApplication = None self.Size=size self.ElementPadding = element_padding or DEFAULT_ELEMENT_PADDING + self.FocusElement = None # ------------------------- Add ONE Row to Form ------------------------- # def AddRow(self, *args): @@ -3215,7 +3218,8 @@ def BuildResultsForSubform(form, initialize_only, top_level_form): if element.Type == ELEM_TYPE_INPUT_TEXT: value = element.QT_QLineEdit.text() if not top_level_form.NonBlocking and not element.do_not_clear and not top_level_form.ReturnKeyboardEvents: - pass + element.QT_QLineEdit.setText('') + elif element.Type == ELEM_TYPE_INPUT_CHECKBOX: value = element.QT_Checkbox.isChecked() elif element.Type == ELEM_TYPE_INPUT_RADIO: @@ -3253,6 +3257,8 @@ def BuildResultsForSubform(form, initialize_only, top_level_form): value = element.QT_Slider.value() elif element.Type == ELEM_TYPE_INPUT_MULTILINE: value = element.QT_TextEdit.toPlainText() + if not top_level_form.NonBlocking and not element.do_not_clear and not top_level_form.ReturnKeyboardEvents: + element.QT_TextEdit.setText('') elif element.Type == ELEM_TYPE_TAB_GROUP: value = 0 elif element.Type == ELEM_TYPE_TABLE: @@ -3527,6 +3533,7 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): # print(style) column_layout = QFormLayout() column_vbox = QVBoxLayout() + PackFormIntoFrame(element, column_layout, toplevel_win) column_vbox.addLayout(column_layout) column_widget.setLayout(column_vbox) @@ -3557,7 +3564,7 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): if element.Tooltip: element.QT_Label.setToolTip(element.Tooltip) - # element.QT_Label.setMargin(element.Pad[0]) + qt_row_layout.setContentsMargins(element.Pad[0], element.Pad[0], element.Pad[1], element.Pad[1]) qt_row_layout.addWidget(element.QT_Label) # ------------------------- BUTTON element ------------------------- # elif element_type == ELEM_TYPE_BUTTON: @@ -3581,6 +3588,8 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): if element.Disabled: element.QT_QPushButton.setDisabled(True) + qt_row_layout.setContentsMargins(element.Pad[0], element.Pad[0], element.Pad[1], element.Pad[1]) + qt_row_layout.addWidget(element.QT_QPushButton) # if element.Pad[0] is not None: # element.QT_QPushButton.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) @@ -3607,7 +3616,12 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): if element_size[1] is not None: element.QT_QLineEdit.setFixedHeight(element_size[1]) # element.QT_QLineEdit.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) - # qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) + if (element.Focus or toplevel_win.UseDefaultFocus) and not focus_set: + focus_set = True + toplevel_win.FocusElement = element.QT_QLineEdit + + qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) + qt_row_layout.addWidget(element.QT_QLineEdit) # ------------------------- COMBO BOX (Drop Down) element ------------------------- # elif element_type == ELEM_TYPE_INPUT_COMBO: @@ -3633,8 +3647,8 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): if element_size[1] is not None: element.QT_ComboBox.setFixedHeight(element_size[1]) - element.QT_ComboBox.addItems(element.Values) + element.QT_ComboBox.setMaxVisibleItems(element.VisibleItems) element.QT_ComboBox.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) qt_row_layout.addWidget(element.QT_ComboBox) # ------------------------- OPTION MENU (Like ComboBox but different) element ------------------------- # @@ -3659,6 +3673,15 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): if element_size[1] is not None: element.QT_ListWidget.setFixedHeight(element_size[1]) + if element.SelectMode == SELECT_MODE_MULTIPLE: + element.QT_ListWidget.setSelectionMode(QAbstractItemView.MultiSelection) + elif element.SelectMode == SELECT_MODE_EXTENDED: + element.QT_ListWidget.setSelectionMode(QAbstractItemView.ExtendedSelection) + elif element.SelectMode == SELECT_MODE_CONTIGUOUS: + element.QT_ListWidget.setSelectionMode(QAbstractItemView.ContiguousSelection) + elif element.SelectMode == SELECT_MODE_SINGLE: + element.QT_ListWidget.setSelectionMode(QAbstractItemView.SingleSelection) + element.QT_ListWidget.addItems(element.Values) qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) @@ -3687,7 +3710,12 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): element.QT_TextEdit.setPlaceholderText(default_text) qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) - # element.QT_TextEdit.installEventFilter(element) + element.MultiQWidget = Multiline.MultiQWidget(element.QT_TextEdit, element) + element.QT_TextEdit.installEventFilter(element.MultiQWidget) + + if (element.Focus or toplevel_win.UseDefaultFocus) and not focus_set: + focus_set = True + toplevel_win.FocusElement = element.QT_TextEdit qt_row_layout.addWidget(element.QT_TextEdit) @@ -3716,13 +3744,15 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): element.QT_TextBrowser.insertPlainText(default_text) element.QT_TextBrowser.moveCursor(QtGui.QTextCursor.End) qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) - qt_row_layout.addWidget(element.QT_TextBrowser) # ------------------------- INPUT CHECKBOX element ------------------------- # elif element_type == ELEM_TYPE_INPUT_CHECKBOX: width = 0 if auto_size_text else element_size[0] default_value = element.InitialState element.QT_Checkbox = QCheckBox(element.Text) + element.QT_Checkbox.setChecked(element.InitialState) + if element.Disabled: + element.QT_Checkbox.setDisabled(True) style = '' if font is not None: style += 'font-family: %s;'%font[0] @@ -3739,7 +3769,6 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): if element_size[1] is not None: element.QT_Checkbox.setFixedHeight(element_size[1]) qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) - qt_row_layout.addWidget(element.QT_Checkbox) # ------------------------- PROGRESS BAR element ------------------------- # elif element_type == ELEM_TYPE_PROGRESS_BAR: @@ -3768,6 +3797,15 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): element.QT_Radio_Button.setFixedHeight(element_size[1]) qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) + if element.GroupID in toplevel_win.RadioDict: + QT_RadioButtonGroup = toplevel_win.RadioDict[element.GroupID] + else: + QT_RadioButtonGroup = QButtonGroup(toplevel_win.QTApplication) + toplevel_win.RadioDict[element.GroupID] = QT_RadioButtonGroup + + QT_RadioButtonGroup.addButton(element.QT_Radio_Button) + + qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) qt_row_layout.addWidget(element.QT_Radio_Button) # ------------------------- INPUT SPIN Box element ------------------------- # @@ -3790,6 +3828,7 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): element.QT_Spinner.setFixedWidth(element_size[0]) if element_size[1] is not None: element.QT_Spinner.setFixedHeight(element_size[1]) + qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) qt_row_layout.addWidget(element.QT_Spinner) @@ -3860,14 +3899,21 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): pass # ------------------------- SLIDER Box element ------------------------- # elif element_type == ELEM_TYPE_INPUT_SLIDER: - - element.Qt_init() + element.QT_Slider = QSlider() + if element.Orientation.startswith('h'): + element.QT_Slider.setOrientation(Qt.Horizontal) + else: + element.QT_Slider.setOrientation(Qt.Vertical) + element.QT_Slider.setMinimum(element.Range[0]) + element.QT_Slider.setMaximum(element.Range[1]) + element.QT_Slider.setTickPosition(QSlider.TicksBothSides) + element.QT_Slider.setTickInterval(element.Range[1] / 10) if element_size[0] is not None: element.QT_Slider.setFixedWidth(element_size[0]) if element_size[1] is not None: element.QT_Slider.setFixedHeight(element_size[1]) + element.QT_Slider.setValue(element.DefaultValue) qt_row_layout.setContentsMargins(element.Pad[0],element.Pad[0],element.Pad[1], element.Pad[1]) - qt_row_layout.addWidget(element.QT_Slider) # ------------------------- DIAL element ------------------------- # @@ -3958,11 +4004,10 @@ def StartupTK(window): window.QTWindow.setWindowFlags(Qt.FramelessWindowHint) if window.AlphaChannel: window.QTWindow.setWindowOpacity(window.AlphaChannel) - - if window.Size != (None, None): window.QTWindow.resize(window.Size[0], window.Size[1]) - + if window.WindowIcon is not None: + window.QTWindow.setWindowIcon(QtGui.QIcon(window.WindowIcon)) # window.QTWindow.setAttribute(Qt.WA_TranslucentBackground) # shadow = QtWidgets.QGraphicsDropShadowEffect() @@ -3970,8 +4015,8 @@ def StartupTK(window): # shadow.setBlurRadius(50) # window.QTWindow.setGraphicsEffect(shadow) - if window.KeepOnTop: - window.QTWindow.setWindowFlags(Qt.WindowStaysOnTopHint) + # if window.KeepOnTop: + # window.QTWindow.setWindowFlags(Qt.WindowStaysOnTopHint) style = '' @@ -4024,6 +4069,8 @@ def StartupTK(window): pass #### RUN MAIN LOOP HERE ##### window.QTWindow.setLayout(window.QT_Box_Layout) + if window.FocusElement is not None: + window.FocusElement.setFocus() window.QTWindow.show() ####### The thing that causes the window to be visible ###### diff --git a/PySimpleGUI_Qt/question.ico b/PySimpleGUI_Qt/question.ico new file mode 100644 index 00000000..c5bccb55 Binary files /dev/null and b/PySimpleGUI_Qt/question.ico differ