From b6ed299d274ce1d19e656d29f78b4a23163bf209 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Tue, 6 Nov 2018 14:06:54 -0500 Subject: [PATCH] Pre-Alpha PySimpleGUI_Qt --- QtVersionExperimental/PySimpleGUI_Qt.py | 533 +++++++++++++++--- QtVersionExperimental/Qt_All_Widgets.py | 66 +++ QtVersionExperimental/Qt_Dial.py | 17 + QtVersionExperimental/Qt_Test.py | 34 +- .../__pycache__/PySimpleGUI_Qt.cpython-36.pyc | Bin 0 -> 126227 bytes 5 files changed, 556 insertions(+), 94 deletions(-) create mode 100644 QtVersionExperimental/Qt_All_Widgets.py create mode 100644 QtVersionExperimental/Qt_Dial.py create mode 100644 QtVersionExperimental/__pycache__/PySimpleGUI_Qt.cpython-36.pyc diff --git a/QtVersionExperimental/PySimpleGUI_Qt.py b/QtVersionExperimental/PySimpleGUI_Qt.py index bbf05c9d..aefb116f 100644 --- a/QtVersionExperimental/PySimpleGUI_Qt.py +++ b/QtVersionExperimental/PySimpleGUI_Qt.py @@ -5,9 +5,13 @@ import datetime import textwrap import pickle import calendar -from PySide2.QtWidgets import QApplication, QLabel, QWidget, QLineEdit, QComboBox, QFormLayout, QVBoxLayout, QHBoxLayout, QListWidget -from PySide2.QtWidgets import QSlider, QCheckBox, QRadioButton, QSpinBox, QPushButton +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 QSpacerItem, QFrame, QGroupBox from PySide2.QtCore import Qt +import PySide2.QtGui as QtGui + + """ The QT version if PySimpleGUI. @@ -56,8 +60,8 @@ def TimerStop(): # ----====----====----==== Constants the user CAN safely change ====----====----====----# DEFAULT_WINDOW_ICON = 'default_icon.ico' -DEFAULT_ELEMENT_SIZE = (45, 1) # In CHARACTERS -DEFAULT_BUTTON_ELEMENT_SIZE = (10, 1) # In CHARACTERS +DEFAULT_ELEMENT_SIZE = (250, 30) # In PIXELS +DEFAULT_BUTTON_ELEMENT_SIZE = (80, 30 ) # In PIXELS DEFAULT_MARGINS = (10, 5) # Margins for each LEFT/RIGHT margin is first term DEFAULT_ELEMENT_PADDING = (5, 3) # Padding between elements (row, col) in pixels DEFAULT_AUTOSIZE_TEXT = True @@ -177,6 +181,7 @@ class MyWindows(): self.NumOpenWindows = 0 self.user_defined_icon = None self.hidden_master_root = None + self.QTApplication = None def Decrement(self): self.NumOpenWindows -= 1 * (self.NumOpenWindows != 0) # decrement if not 0 @@ -232,6 +237,7 @@ ELEM_TYPE_GRAPH = 'graph' ELEM_TYPE_TAB = 'tab' ELEM_TYPE_TAB_GROUP = 'tabgroup' ELEM_TYPE_INPUT_SLIDER = 'slider' +ELEM_TYPE_INPUT_DIAL = 'dial' ELEM_TYPE_INPUT_LISTBOX = 'listbox' ELEM_TYPE_OUTPUT = 'output' ELEM_TYPE_COLUMN = 'column' @@ -242,6 +248,7 @@ ELEM_TYPE_TABLE = 'table' ELEM_TYPE_TREE = 'tree' ELEM_TYPE_ERROR = 'error' ELEM_TYPE_SEPARATOR = 'separator' +ELEM_TYPE_STRETCH = 'stretch' # ------------------------- Popup Buttons Types ------------------------- # POPUP_BUTTONS_YES_NO = 1 @@ -264,7 +271,7 @@ POPUP_BUTTONS_NO_BUTTONS = 5 # ------------------------------------------------------------------------- # class Element(): def __init__(self, type, size=(None, None), auto_size_text=None, font=None, background_color=None, text_color=None, - key=None, pad=None, tooltip=None): + key=None, pad=None, tooltip=None, size_px=(None,None)): self.Size = size self.Type = type self.AutoSizeText = auto_size_text @@ -286,6 +293,7 @@ class Element(): self.Key = key # dictionary key for return values self.Tooltip = tooltip self.TooltipObject = None + self.SizePx = size_px def FindReturnKeyBoundButton(self, form): for row in form.Rows: @@ -463,7 +471,7 @@ Input = InputText # ---------------------------------------------------------------------- # # Combo # # ---------------------------------------------------------------------- # -class InputCombo(Element): +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): @@ -487,6 +495,11 @@ class InputCombo(Element): 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) + + def Qt_init(self): + self.QT_Combobox = QComboBox() + self.QT_Combobox.addItems(self.Values) + def Update(self, value=None, values=None, set_to_index=None, disabled=None, readonly=None, font=None): if values is not None: try: @@ -530,7 +543,7 @@ class InputCombo(Element): # ------------------------- INPUT COMBO Element lazy functions ------------------------- # -Combo = InputCombo +InputCombo = Combo DropDown = InputCombo Drop = InputCombo @@ -891,7 +904,7 @@ class Multiline(Element): # Text # # ---------------------------------------------------------------------- # class Text(Element): - def __init__(self, text, size=(None, None), auto_size_text=None, click_submits=None, relief=None, font=None, + def __init__(self, text, size=(None, None), size_px=(None, None), auto_size_text=None, click_submits=None, relief=None, font=None, text_color=None, background_color=None, justification=None, pad=None, key=None, tooltip=None): ''' Text Element @@ -910,26 +923,40 @@ class Text(Element): ''' self.DisplayText = text self.TextColor = text_color if text_color else DEFAULT_TEXT_COLOR - self.Justification = justification + self.Justification = justification or 'left' self.Relief = relief self.ClickSubmits = click_submits if background_color is None: bg = DEFAULT_TEXT_ELEMENT_BACKGROUND_COLOR else: bg = background_color + self.QT_Label = None + super().__init__(ELEM_TYPE_TEXT, size, auto_size_text, background_color=bg, font=font if font else DEFAULT_FONT, - text_color=self.TextColor, pad=pad, key=key, tooltip=tooltip) + text_color=self.TextColor, pad=pad, key=key, tooltip=tooltip, size_px=size_px) return + + + def Update(self, value=None, background_color=None, text_color=None, font=None): if value is not None: self.DisplayText = value + self.QT_Label.setText(value) + style = '' + temp_font = font if font is not None else self.Font + if temp_font is None: + temp_font = DEFAULT_FONT + if temp_font is not None: + style += 'font-family: %s;' % temp_font[0] + style += 'font-size: %spt;' % temp_font[1] + temp_text_color = text_color or self.TextColor + style += 'color: %s;' % temp_text_color if background_color is not None: - pass - if text_color is not None: - pass - if font is not None: - pass + style += 'background-color: %s;' % background_color + self.QT_Label.setStyleSheet(style) + + def __del__(self): super().__del__() @@ -1007,6 +1034,8 @@ class Button(Element): self.Target = target self.ButtonText = button_text self.ButtonColor = button_color if button_color else DEFAULT_BUTTON_COLOR + self.TextColor = self.ButtonColor[0] + self.BackgroundColor = self.ButtonColor[1] self.ImageFilename = image_filename self.ImageData = image_data self.ImageSize = image_size @@ -1021,8 +1050,9 @@ class Button(Element): self.InitialFolder = initial_folder self.Disabled = disabled self.ChangeSubmits = change_submits + self.QT_Push_Button = None - super().__init__(ELEM_TYPE_BUTTON, size=size, font=font, pad=pad, key=key, tooltip=tooltip) + super().__init__(ELEM_TYPE_BUTTON, size=size, font=font, pad=pad, key=key, tooltip=tooltip, text_color=self.TextColor, background_color=self.BackgroundColor) return # Realtime button release callback @@ -1044,6 +1074,7 @@ class Button(Element): def ButtonCallBack(self): global _my_windows + # print('Button callback') # print(f'Parent = {self.ParentForm} Position = {self.Position}') @@ -1097,7 +1128,7 @@ class Button(Element): self.ParentForm.FormRemainedOpen = False self.ParentForm._Close() if self.ParentForm.CurrentlyRunningMainloop: - pass # quit mainloop + self.ParentForm.QTApplication.exit() # Exit the mainloop if self.ParentForm.NonBlocking: # TODO DESTROY WIN _my_windows.Decrement() @@ -1110,7 +1141,7 @@ class Button(Element): self.ParentForm.LastButtonClicked = self.ButtonText self.ParentForm.FormRemainedOpen = True if self.ParentForm.CurrentlyRunningMainloop: # if this window is running the mainloop, kick out - pass # kick the users out of the mainloop + self.ParentForm.QTApplication.exit() elif self.BType == BUTTON_TYPE_CLOSES_WIN_ONLY: # special kind of button that does not exit main loop self.ParentForm._Close() if self.ParentForm.NonBlocking: @@ -1123,27 +1154,41 @@ class Button(Element): self.ParentForm.LastButtonClicked = target_element.Key self.ParentForm.FormRemainedOpen = True if self.ParentForm.CurrentlyRunningMainloop: - pass # TODO # kick the sssssssssssssssssssssssssssssssssssssssssusers out of the mainloop + pass # TODO # kick the users out of the mainloop return def Update(self, text=None, button_color=(None, None), disabled=None, image_data=None, image_filename=None): - try: - if text is not None: - self.TKButton.configure(text=text) - self.ButtonText = text - if button_color != (None, None): - self.TKButton.config(foreground=button_color[0], background=button_color[1]) - except: - return - if disabled == True: - pass - elif disabled == False: - pass - if image_data is not None: - pass - if image_filename is not None: - pass + if text is not None: + self.QT_Push_Button.setText(text) + self.ButtonText = text + style = '' + + if self.ParentForm.Font and (self.Font == DEFAULT_FONT or not self.Font): + font = self.ParentForm.Font + elif self.Font is not None: + font = self.Font + else: + font = DEFAULT_FONT + + if font is not None: + style += 'font-family: %s;' % font[0] + style += 'font-size: %spt;' % font[1] + + if button_color != (None, None): + style += 'color: %s;' % button_color[0] + style += 'background-color: %s;' % button_color[1] + if style != '': + self.QT_Push_Button.setStyleSheet(style) + if disabled: + self.QT_Push_Button.setDisabled(True) + elif disabled is False: + self.QT_Push_Button.setDisabled(False) + style = '' + + + + def GetText(self): return self.ButtonText @@ -1707,12 +1752,25 @@ class Slider(Element): self.TickInterval = tick_interval temp_size = size if temp_size == (None, None): - temp_size = (20, 20) if self.Orientation.startswith('h') else (8, 20) + temp_size = (150, 30) if self.Orientation.startswith('h') else (30, 150) + + super().__init__(ELEM_TYPE_INPUT_SLIDER, size=temp_size, font=font, background_color=background_color, 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: pass @@ -1736,6 +1794,112 @@ class Slider(Element): def __del__(self): super().__del__() +# ---------------------------------------------------------------------- # +# Dial # +# ---------------------------------------------------------------------- # +class Dial(Element): + def __init__(self, range=(None, None), default_value=None, resolution=None, tick_interval=None, orientation=None, + border_width=None, relief=None, change_submits=False, disabled=False, size=(None, None), font=None, + background_color=None, text_color=None, key=None, pad=None, tooltip=None): + ''' + Slider Element + :param range: + :param default_value: + :param resolution: + :param orientation: + :param border_width: + :param relief: + :param change_submits: + :param disabled: + :param size: + :param font: + :param background_color: + :param text_color: + :param key: + :param pad: + :param tooltip: + ''' + self.TKScale = None + self.Range = (1, 10) if range == (None, None) else range + self.DefaultValue = self.Range[0] if default_value is None else default_value + self.Orientation = orientation if orientation else DEFAULT_SLIDER_ORIENTATION + self.BorderWidth = border_width if border_width else DEFAULT_SLIDER_BORDER_WIDTH + self.Relief = relief if relief else DEFAULT_SLIDER_RELIEF + self.Resolution = 1 if resolution is None else resolution + self.ChangeSubmits = change_submits + self.Disabled = disabled + self.TickInterval = tick_interval + temp_size = size + if temp_size == (None, None): + temp_size = (20, 20) if self.Orientation.startswith('h') else (8, 20) + + super().__init__(ELEM_TYPE_INPUT_DIAL, size=temp_size, font=font, background_color=background_color, + text_color=text_color, key=key, pad=pad, tooltip=tooltip) + return + + + def Qt_init(self): + self.QT_Dial = QDial() + self.QT_Dial.setMinimum(self.Range[0]) + self.QT_Dial.setMaximum(self.Range[1]) + + def Update(self, value=None, range=(None, None), disabled=None): + if value is not None: + pass + self.DefaultValue = value + if disabled == True: + pass + elif disabled == False: + pass + + def SliderChangedHandler(self, event): + # first, get the results table built + # modify the Results table in the parent FlexForm object + if self.Key is not None: + self.ParentForm.LastButtonClicked = self.Key + else: + self.ParentForm.LastButtonClicked = '' + self.ParentForm.FormRemainedOpen = True + if self.ParentForm.CurrentlyRunningMainloop: + pass # TODO # kick the users out of the mainloop + + def __del__(self): + super().__del__() + + + +# ---------------------------------------------------------------------- # +# Stretch # +# ---------------------------------------------------------------------- # +class Stretch(Element): + def __init__(self, size=(None, None), font=None, background_color=None, text_color=None, key=None, pad=None, tooltip=None): + ''' + Slider Element + :param range: + :param default_value: + :param resolution: + :param orientation: + :param border_width: + :param relief: + :param change_submits: + :param disabled: + :param size: + :param font: + :param background_color: + :param text_color: + :param key: + :param pad: + :param tooltip: + ''' + + super().__init__(ELEM_TYPE_STRETCH, size=size, font=font, background_color=background_color, + text_color=text_color, key=key, pad=pad, tooltip=tooltip) + return + + + def __del__(self): + super().__del__() + # ---------------------------------------------------------------------- # # Column # @@ -2151,6 +2315,7 @@ class Window: self.TimerCancelled = False self.DisableClose = disable_close self._Hidden = False + self.QTApplication = None # ------------------------- Add ONE Row to Form ------------------------- # def AddRow(self, *args): @@ -2305,7 +2470,7 @@ class Window: ################################# CALL GUI MAINLOOP ############################ self.QTApplication.exec_() - self.LastButtonClicked = 'TEST' + # self.LastButtonClicked = 'TEST' self.CurrentlyRunningMainloop = False self.TimerCancelled = True if self.RootNeedsDestroying: @@ -2328,15 +2493,14 @@ class Window: return None, None if not self.Shown: self.Show(non_blocking=True) - try: - rc = self.TKroot.update() - except: + if 0: # TODO add window closed with X logic self.TKrootDestroyed = True _my_windows.Decrement() # print("read failed") # return None, None return BuildResults(self, False, self) + def Finalize(self): if self.TKrootDestroyed: return self @@ -2349,7 +2513,6 @@ class Window: _my_windows.Decrement() # return None, None return self - def Refresh(self): if self.TKrootDestroyed: return self @@ -2957,10 +3120,12 @@ def BuildResultsForSubform(form, initialize_only, top_level_form): value = [] elif element.Type == ELEM_TYPE_INPUT_SPIN: value = element.QT_Spinner.value() + elif element.Type == ELEM_TYPE_INPUT_DIAL: + value = element.QT_Dial.value() elif element.Type == ELEM_TYPE_INPUT_SLIDER: value = element.QT_Slider.value() elif element.Type == ELEM_TYPE_INPUT_MULTILINE: - value = 0 + value = element.QT_TextEdit.toPlainText() elif element.Type == ELEM_TYPE_TAB_GROUP: value = 0 elif element.Type == ELEM_TYPE_TABLE: @@ -3214,7 +3379,7 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): # Set foreground color text_color = element.TextColor # Determine Element size - element_size = element.Size + element_size = element.Size if element.Size != (None, None) else element.SizePx if (element_size == (None, None) and element_type != ELEM_TYPE_BUTTON): # user did not specify a size element_size = toplevel_win.DefaultElementSize elif (element_size == (None, None) and element_type == ELEM_TYPE_BUTTON): @@ -3223,37 +3388,122 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): auto_size_text = False # if user has specified a size then it shouldn't autosize # ------------------------- COLUMN element ------------------------- # if element_type == ELEM_TYPE_COLUMN: - if element.Scrollable: - pass - else: - pass + column_widget = QWidget() + + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + column_widget.setStyleSheet(style) + print(style) + column_layout = QFormLayout() + column_vbox = QVBoxLayout() + PackFormIntoFrame(element, column_layout, toplevel_win) + column_vbox.addLayout(column_layout) + column_widget.setLayout(column_vbox) + qt_row_layout.addWidget(column_widget) # ------------------------- TEXT element ------------------------- # elif element_type == ELEM_TYPE_TEXT: - # auto_size_text = element.AutoSizeText - display_text = element.DisplayText # text to display - element.QT_label = QLabel(display_text, toplevel_win.QTWindow) - qt_row_layout.addWidget(element.QT_label) + element.QT_Label = QLabel(element.DisplayText, toplevel_win.QTWindow) + if element.Justification[0] == 'c': + element.QT_Label.setAlignment(Qt.AlignCenter) + elif element.Justification[0] == 'r': + element.QT_Label.setAlignment(Qt.AlignRight) + if not auto_size_text: + if element_size[0] is not None: + element.QT_Label.setFixedWidth(element_size[0]) + if element_size[1] is not None: + element.QT_Label.setFixedHeight(element_size[1]) + # element.QT_Label.setWordWrap(True) + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_Label.setStyleSheet(style) + + if element.Tooltip: + element.QT_Label.setToolTip(element.Tooltip) + qt_row_layout.addWidget(element.QT_Label) # ------------------------- BUTTON element ------------------------- # elif element_type == ELEM_TYPE_BUTTON: btext = element.ButtonText btype = element.BType element.QT_Push_Button = QPushButton(btext) + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_Push_Button.setStyleSheet(style) + if element.AutoSizeButton is False or toplevel_win.AutoSizeButtons is False or element.Size[0] is not None: + if element_size[0] is not None: + element.QT_Push_Button.setFixedWidth(element_size[0]) + if element_size[1] is not None: + element.QT_Push_Button.setFixedHeight(element_size[1]) + + if element.Disabled: + element.QT_Push_Button.setDisabled(True) + qt_row_layout.addWidget(element.QT_Push_Button) - element.QT_Push_Button.clicked.connect(window.QTApplication.exit) + element.QT_Push_Button.clicked.connect(element.ButtonCallBack) + # element.QT_Push_Button.clicked.connect(window.QTApplication.exit) # ------------------------- INPUT (Single Line) element ------------------------- # elif element_type == ELEM_TYPE_INPUT_TEXT: default_text = element.DefaultText element.QT_LineEdit = QLineEdit() element.QT_LineEdit.setPlaceholderText(default_text) + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_LineEdit.setStyleSheet(style) + + if element.AutoSizeText is False or toplevel_win.AutoSizeButtons is False or element.Size[0] is not None: + if element_size[0] is not None: + element.QT_LineEdit.setFixedWidth(element_size[0]) + if element_size[1] is not None: + element.QT_LineEdit.setFixedHeight(element_size[1]) + + qt_row_layout.addWidget(element.QT_LineEdit) # ------------------------- COMBO BOX (Drop Down) element ------------------------- # elif element_type == ELEM_TYPE_INPUT_COMBO: + element.QT_Combobox = QComboBox() max_line_len = max([len(str(l)) for l in element.Values]) if auto_size_text is False: width = element_size[0] else: width = max_line_len - element.QT_Combobox = QComboBox() + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_Combobox.setStyleSheet(style) + + if not auto_size_text: + if element_size[0] is not None: + element.QT_Combobox.setFixedWidth(element_size[0]) + if element_size[1] is not None: + element.QT_Combobox.setFixedHeight(element_size[1]) + + element.QT_Combobox.addItems(element.Values) qt_row_layout.addWidget(element.QT_Combobox) # ------------------------- OPTION MENU (Like ComboBox but different) element ------------------------- # @@ -3263,17 +3513,67 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): elif element_type == ELEM_TYPE_INPUT_LISTBOX: max_line_len = max([len(str(l)) for l in element.Values]) if len(element.Values) != 0 else 0 element.QT_List_Widget = QListWidget() + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_List_Widget.setStyleSheet(style) + if not auto_size_text: + if element_size[0] is not None: + element.QT_List_Widget.setFixedWidth(element_size[0]) + if element_size[1] is not None: + element.QT_List_Widget.setFixedHeight(element_size[1]) + element.QT_List_Widget.addItems(element.Values) qt_row_layout.addWidget(element.QT_List_Widget) # ------------------------- INPUT MULTI LINE element ------------------------- # elif element_type == ELEM_TYPE_INPUT_MULTILINE: default_text = element.DefaultText width, height = element_size + element.QT_TextEdit = QTextEdit() + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_TextEdit.setStyleSheet(style) + + if element.AutoSizeText is False or toplevel_win.AutoSizeButtons is False or element.Size[0] is not None: + if element_size[0] is not None: + element.QT_TextEdit.setFixedWidth(element_size[0]) + if element_size[1] is not None: + element.QT_TextEdit.setFixedHeight(element_size[1]) + + element.QT_TextEdit.setPlaceholderText(default_text) + qt_row_layout.addWidget(element.QT_TextEdit) # ------------------------- 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) + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_Checkbox.setStyleSheet(style) + + if element.AutoSizeText is False or toplevel_win.AutoSizeButtons is False or element.Size[0] is not None: + if element_size[0] is not None: + element.QT_Checkbox.setFixedWidth(element_size[0]) + if element_size[1] is not None: + element.QT_Checkbox.setFixedHeight(element_size[1]) + qt_row_layout.addWidget(element.QT_Checkbox) # ------------------------- PROGRESS BAR element ------------------------- # elif element_type == ELEM_TYPE_PROGRESS_BAR: @@ -3285,6 +3585,22 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): default_value = element.InitialState ID = element.GroupID element.QT_Radio_Button = QRadioButton(element.Text) + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_Radio_Button.setStyleSheet(style) + + if element.AutoSizeText is False or toplevel_win.AutoSizeButtons is False or element.Size[0] is not None: + if element_size[0] is not None: + element.QT_Radio_Button.setFixedWidth(element_size[0]) + if element_size[1] is not None: + element.QT_Radio_Button.setFixedHeight(element_size[1]) + qt_row_layout.addWidget(element.QT_Radio_Button) # ------------------------- INPUT SPIN Box element ------------------------- # @@ -3292,7 +3608,22 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): width, height = element_size width = 0 if auto_size_text else element_size[0] element.QT_Spinner = QSpinBox() + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_Spinner.setStyleSheet(style) element.QT_Spinner.setRange(element.Values[0], element.Values[1]) + if not auto_size_text: + if element_size[0] is not None: + element.QT_Spinner.setFixedWidth(element_size[0]) + if element_size[1] is not None: + element.QT_Spinner.setFixedHeight(element_size[1]) + qt_row_layout.addWidget(element.QT_Spinner) # ------------------------- OUTPUT element ------------------------- # elif element_type == ELEM_TYPE_OUTPUT: @@ -3311,7 +3642,24 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): menu_def = element.MenuDefinition # ------------------------- Frame element ------------------------- # elif element_type == ELEM_TYPE_FRAME: - pass + column_widget = QGroupBox() + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + column_widget.setStyleSheet(style) + + column_widget.setTitle(element.Title) + column_layout = QFormLayout() + column_vbox = QVBoxLayout() + PackFormIntoFrame(element, column_layout, toplevel_win) + column_vbox.addLayout(column_layout) + column_widget.setLayout(column_vbox) + qt_row_layout.addWidget(column_widget) # ------------------------- Tab element ------------------------- # elif element_type == ELEM_TYPE_TAB: pass @@ -3320,17 +3668,31 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): pass # ------------------------- SLIDER Box element ------------------------- # elif element_type == ELEM_TYPE_INPUT_SLIDER: - 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) + + element.Qt_init() + 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]) qt_row_layout.addWidget(element.QT_Slider) + + # ------------------------- DIAL element ------------------------- # + elif element_type == ELEM_TYPE_INPUT_DIAL: + element.Qt_init() + style = '' + if font is not None: + style += 'font-family: %s;'%font[0] + style += 'font-size: %spt;'%font[1] + if element.TextColor is not None: + style += 'color: %s;' % element.TextColor + if element.BackgroundColor is not None: + style += 'background-color: %s;' % element.BackgroundColor + element.QT_Dial.setStyleSheet(style) + qt_row_layout.addWidget(element.QT_Dial) + # ------------------------- Stretch element ------------------------- # + elif element_type == ELEM_TYPE_STRETCH: + qt_row_layout.addStretch(1) # ------------------------- TABLE element ------------------------- # elif element_type == ELEM_TYPE_TABLE: pass @@ -3342,7 +3704,7 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win): pass # ............................DONE WITH ROW pack the row of widgets ..........................# - window.QFormLayout.addRow('', qt_row_layout) + containing_frame.addRow('', qt_row_layout) # done with row, pack the row of widgets # tk_row_frame.grid(row=row_num+2, sticky=tk.NW, padx=DEFAULT_MARGINS[0]) @@ -3353,7 +3715,7 @@ def ConvertFlexToTK(window): InitializeResults(window) pass master = 000000 - PackFormIntoFrame(window, master, window) + PackFormIntoFrame(window, window.QFormLayout, window) # ....................................... DONE creating and laying out window ..........................# screen_width = 000000 # get window info to move to middle of screen screen_height = 000000 @@ -3389,12 +3751,18 @@ def StartupTK(window): else: root =000000 - window.QTApplication = QApplication(sys.argv) + if _my_windows.QTApplication is None: + _my_windows.QTApplication = QApplication(sys.argv) + + window.QTApplication = _my_windows.QTApplication window.QTWindow = QWidget() + style = '' + if window.BackgroundColor is not None: + style += 'background-color: %s;' % window.BackgroundColor + window.QTWindow.setStyleSheet(style) window.QTWindow.setWindowTitle(window.Title) - # root.wm_overrideredirect(True) if window.BackgroundColor is not None and window.BackgroundColor != COLOR_SYSTEM_DEFAULT: root = 000000 _my_windows.Increment() @@ -3407,13 +3775,14 @@ def StartupTK(window): if window.KeepOnTop: pass - # root.protocol("WM_DELETE_WINDOW", MyFlexForm.DestroyedCallback()) - # root.bind('', MyFlexForm.DestroyedCallback()) window.QFormLayout = QFormLayout() window.QT_Box_Layout = QVBoxLayout() ConvertFlexToTK(window) window.QT_Box_Layout.addLayout(window.QFormLayout) + + + # Make window visible again pass @@ -3433,12 +3802,12 @@ def StartupTK(window): window.QTApplication.exec_() window.CurrentlyRunningMainloop = False window.TimerCancelled = True - window.LastButtonClicked = 'Test' + # window.LastButtonClicked = 'Test' # print('..... BACK from MainLoop') if not window.FormRemainedOpen: _my_windows.Decrement() if window.RootNeedsDestroying: - window.TKroot.destroy() + window.QTWindow.close() # destroy the window window.RootNeedsDestroying = False return @@ -4452,20 +4821,20 @@ def Popup(*args, button_color=None, background_color=None, text_color=None, butt # show either an OK or Yes/No depending on paramater if button_type is POPUP_BUTTONS_YES_NO: window.AddRow(PopupButton('Yes', button_color=button_color, focus=True, bind_return_key=True, pad=((20, 5), 3), - size=(5, 1)), PopupButton('No', button_color=button_color, size=(5, 1))) + size=(60, 20)), PopupButton('No', button_color=button_color, size=(60, 20))) elif button_type is POPUP_BUTTONS_CANCELLED: window.AddRow( PopupButton('Cancelled', button_color=button_color, focus=True, bind_return_key=True, pad=((20, 0), 3))) elif button_type is POPUP_BUTTONS_ERROR: - window.AddRow(PopupButton('Error', size=(6, 1), button_color=button_color, focus=True, bind_return_key=True, + window.AddRow(PopupButton('Error', size=(60, 20), button_color=button_color, focus=True, bind_return_key=True, pad=((20, 0), 3))) elif button_type is POPUP_BUTTONS_OK_CANCEL: - window.AddRow(PopupButton('OK', size=(6, 1), button_color=button_color, focus=True, bind_return_key=True), - PopupButton('Cancel', size=(6, 1), button_color=button_color)) + window.AddRow(PopupButton('OK', size=(60, 20), button_color=button_color, focus=True, bind_return_key=True), + PopupButton('Cancel', size=(60, 20), button_color=button_color)) elif button_type is POPUP_BUTTONS_NO_BUTTONS: pass else: - window.AddRow(PopupButton('OK', size=(5, 1), button_color=button_color, focus=True, bind_return_key=True, + window.AddRow(PopupButton('OK', size=(60, 20), button_color=button_color, focus=True, bind_return_key=True, pad=((20, 0), 3))) if non_blocking: @@ -4856,7 +5225,7 @@ def PopupGetFolder(message, default_path='', no_window=False, size=(None, None), layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)], [InputText(default_text=default_path, size=size), FolderBrowse(initial_folder=initial_folder)], - [CloseButton('Ok', size=(5, 1), bind_return_key=True), CloseButton('Cancel', size=(5, 1))]] + [CloseButton('Ok', size=(60, 20), bind_return_key=True), CloseButton('Cancel', size=(60, 20))]] window = Window(title=message, icon=icon, auto_size_text=True, button_color=button_color, background_color=background_color, @@ -4915,7 +5284,7 @@ def PopupGetFile(message, default_path='', default_extension='', save_as=False, layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)], [InputText(default_text=default_path, size=size), browse_button], - [CloseButton('Ok', size=(6, 1), bind_return_key=True), CloseButton('Cancel', size=(6, 1))]] + [CloseButton('Ok', size=(60, 20), bind_return_key=True), CloseButton('Cancel', size=(60, 20))]] window = Window(title=message, icon=icon, auto_size_text=True, button_color=button_color, font=font, background_color=background_color, @@ -4954,7 +5323,7 @@ def PopupGetText(message, default_text='', password_char='', size=(None, None), layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color, font=font)], [InputText(default_text=default_text, size=size, password_char=password_char)], - [CloseButton('Ok', size=(5, 1), bind_return_key=True), CloseButton('Cancel', size=(5, 1))]] + [CloseButton('Ok', size=(60, 20), bind_return_key=True), CloseButton('Cancel', size=(60, 20))]] window = Window(title=message, icon=icon, auto_size_text=True, button_color=button_color, no_titlebar=no_titlebar, background_color=background_color, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, @@ -4970,11 +5339,11 @@ def PopupGetText(message, default_text='', password_char='', size=(None, None), def main(): layout = [[Text('You are running the PySimpleGUI.py file itself')], - [Text('You should be importing it rather than running it', size=(50, 2))], + [Text('You should be importing it rather than running it')], [Text('Here is your sample input window....')], - [Text('Source Folder', size=(15, 1), justification='right'), InputText('Source', focus=True), + [Text('Source Folder', size=(150, 20), justification='right'), InputText('Source', focus=True), FolderBrowse()], - [Text('Destination Folder', size=(15, 1), justification='right'), InputText('Dest'), FolderBrowse()], + [Text('Destination Folder', size=(150, 20), justification='right'), InputText('Dest'), FolderBrowse()], [Ok(), Cancel()]] window = Window('Demo window..').Layout(layout) diff --git a/QtVersionExperimental/Qt_All_Widgets.py b/QtVersionExperimental/Qt_All_Widgets.py new file mode 100644 index 00000000..b6f913e5 --- /dev/null +++ b/QtVersionExperimental/Qt_All_Widgets.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +import sys +if sys.version_info[0] >= 3: + import PySimpleGUI_Qt as sg +else: + import PySimpleGUI27 as sg + +sg.ChangeLookAndFeel('GreenTan') + +# # Column layout +# col = [[sg.Text('col Row 1', text_color='white', background_color='blue')], +# [sg.Text('col Row 2', text_color='white', background_color='blue'), sg.Input('col input 1')], +# [sg.Text('col Row 3', text_color='white', background_color='blue'), sg.Input('col input 2')]] +# # Window layout +# layout = [ [sg.In()], +# [sg.Text('test'), sg.Column(col, background_color='blue')],] +# +# # Display the window and get values +# event, values = sg.Window('Compact 1-line form with column').Layout(layout).Read() +# +# exit() +# ------ 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',text_color='black', justification='center', size=(100,30))], + [sg.Spin((1,10), size=(100,30))], + [sg.Spin((1,10), size=(100,30))], + [sg.Spin((1,10), size=(100,30))],] + +layout = [ + [sg.Menu(menu_def, tearoff=True)], + [sg.Text('(Almost) All widgets in one Window!', size=(600, 50), justification='l', 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', size=(300,30))], + [sg.Frame(layout=[ + [sg.Checkbox('Checkbox', size=(185,30)), sg.Checkbox('My second checkbox!', default=True)], + [sg.Radio('My first Radio!', "RADIO1", default=True, size=(180,30), ),sg.Radio('My second Radio!', "RADIO1")]], title='Options',title_color='red', relief=sg.RELIEF_SUNKEN, tooltip='Use these to set flags', ), sg.Stretch()], + [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(300, 80)), + sg.Multiline(default_text='A second multi-line', size=(300, 80))], + [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(150, 30)), + sg.Slider(range=(1, 100), orientation='h', size=(150, 30), default_value=85)], + [sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))], + [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(200,100)), + sg.Frame('Labelled Group',[[ + sg.Slider(range=(1, 100), orientation='v', default_value=25, tick_interval=25), + sg.Slider(range=(1, 100), orientation='v', default_value=75), + sg.Slider(range=(1, 100), orientation='v', default_value=10), + sg.Column(column1, background_color='lightblue')]]), sg.Stretch()], + [sg.Text('_' * 80)], + [sg.Text('Choose A Folder')], + [sg.Text('Your Folder', auto_size_text=True, justification='right'), + sg.InputText('Default Folder', size=(300,30)), sg.FolderBrowse()], + [sg.Submit(tooltip='Click to submit this form', size=(120,30)), sg.Cancel(size=(120,30))]] + +window = sg.Window('Everything bagel', default_element_size=(40, 1), grab_anywhere=False, font=('Helvetica', 12)).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/QtVersionExperimental/Qt_Dial.py b/QtVersionExperimental/Qt_Dial.py new file mode 100644 index 00000000..4ac86e4b --- /dev/null +++ b/QtVersionExperimental/Qt_Dial.py @@ -0,0 +1,17 @@ +import PySimpleGUI_Qt as sg + +layout = [ + [sg.Text('This is the new Dial Element!')], + [sg.Dial(range=(1,100), key='_DIAL_')], + [sg.Button('Show'), sg.Button('Exit')] + ] + +window = sg.Window('Window Title').Layout(layout) + +while True: # Event Loop + event, values = window.Read() + print(event, values) + if event is None or event == 'Exit': + break + +window.Close() diff --git a/QtVersionExperimental/Qt_Test.py b/QtVersionExperimental/Qt_Test.py index 4145fc0f..2476846b 100644 --- a/QtVersionExperimental/Qt_Test.py +++ b/QtVersionExperimental/Qt_Test.py @@ -1,20 +1,30 @@ import PySimpleGUI_Qt as sg +# sg.Popup('test 1') +# sg.Popup('test 2') +sg.ChangeLookAndFeel('GreenTan') layout = [ - [sg.Text('Hello PySimpleGUI!'),sg.Text(' '*5), sg.Text('On the same row'), ], - [sg.Text('Input something here'), sg.Input('default text')], - [sg.Combo(['Combo 1', 'Combo 2', 'Combo 3'])], - [sg.Listbox(['Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'], size=(30,10)), - sg.Slider((1,100))], - [sg.Slider((1,10), orientation='h')], - [sg.Checkbox('Checkbox 1')], - [sg.Checkbox('Checkbox 2')], - [sg.Checkbox('Checkbox 3')], + [sg.Text('Hello From PySimpleGUI_Qt!', text_color='red', tooltip='This is my tooltip', justification='c', font=('Courier', 22), key='_TEXT_')], + [sg.Text('Input something here'),sg.Stretch(), sg.Input('This is an InputText Element', key='_INPUT_', font=('Any', 14))], + [sg.Text('This is the new Dial Element'), sg.Dial(background_color='red'), sg.Stretch()], + [sg.Combo(['Combo 1', 'Combo 2', 'Combo 3'], key='+COMBO+', size=(150,30), text_color='green')], + [sg.Listbox(['Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'], key='+LIST+', size=(200,150), text_color='blue'),sg.Slider((1,100), orientation='v', key='+SLIDER 1+')], + [sg.Slider((1,10), size=(200,30), orientation='h', key='+SLIDER 2+'), sg.Stretch()], + [sg.Checkbox('Checkbox 1', key='+CB1+'), sg.Checkbox('Checkbox 2', key='+CB2')], + [sg.Checkbox('Checkbox 3'), sg.Checkbox('Checkbox 4')], [sg.Radio('Radio1', group_id=1),sg.Radio('Radio2', group_id=1)], - [sg.Spin((5,8))], - [sg.Button('My Button')], + [sg.Spin((5,8), size=(100,30))], + [sg.Multiline('This is a Multiline Element', key='+MULTI+')], + [sg.Button('My Button', size=(120,30)), sg.Exit(), sg.Button('Change', key='_CHANGE_')], ] -window = sg.Window('My first QT Window').Layout(layout) + +window = sg.Window('My first QT Window', auto_size_text=True, auto_size_buttons=False, font=('Helvetica', 16)).Layout(layout) + while True: event, values = window.Read() print(event, values) + if event is None or event == 'Exit': + break + window.FindElement('_TEXT_').Update(values['_INPUT_'], font=('Helvetica', 30)) + if event == '_CHANGE_': + window.FindElement('_CHANGE_').Update('Disabled', disabled=True, button_color=('gray', 'gray20'),) diff --git a/QtVersionExperimental/__pycache__/PySimpleGUI_Qt.cpython-36.pyc b/QtVersionExperimental/__pycache__/PySimpleGUI_Qt.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c659c4da337fac9e887b3f8074f80fcc6283d2f3 GIT binary patch literal 126227 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