From eff3b977823324f86a15fb89af4b6ac9b8ffd8ea Mon Sep 17 00:00:00 2001
From: MikeTheWatchGuy <mike_barnett@hotmail.com>
Date: Thu, 8 Nov 2018 00:55:40 -0500
Subject: [PATCH] Listbox select modes, return submits for multiline & input,
 max visible items in combobox, radio button groups, set icon, default focus
 set,

---
 Demo_All_Widgets.py              |  54 +++++++++++++
 PySimpleGUI_Qt/Demo_HowDoI.py    |  93 +++++++++++++++++++++
 PySimpleGUI_Qt/PySimpleGUI_Qt.py | 133 +++++++++++++++++++++----------
 PySimpleGUI_Qt/question.ico      | Bin 0 -> 43646 bytes
 4 files changed, 237 insertions(+), 43 deletions(-)
 create mode 100644 Demo_All_Widgets.py
 create mode 100644 PySimpleGUI_Qt/Demo_HowDoI.py
 create mode 100644 PySimpleGUI_Qt/question.ico

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 0000000000000000000000000000000000000000..c5bccb55495ad786497174f359e915209f0acbd6
GIT binary patch
literal 43646
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

literal 0
HcmV?d00001