Merge pull request #1066 from PySimpleGUI/Dev-latest

Dev latest
This commit is contained in:
MikeTheWatchGuy 2019-01-11 10:11:31 -05:00 committed by GitHub
commit c620282650
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 37 deletions

View File

@ -1,45 +1,64 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys import sys
import os
if sys.version_info[0] >= 3: if sys.version_info[0] >= 3:
import PySimpleGUI as sg import PySimpleGUI as sg
else: else:
import PySimpleGUI27 as sg import PySimpleGUI27 as sg
"""
A PySimpleGUI or PySimpleGUIQt demo program that will display a folder heirarchy with icons for the folders and files.
Note that if you are scanning a large folder then tkinter will eventually complain abouit too many bitmaps and crash
Getting events back from clicks on the entries works for PySimpleGUI, but appears to not be implemented in PySimpleGUIQt
If you need tree events using PySimpleGUIQt then post an Issue on the GitHub http://www.PySimpleGUI.com
"""
# Base64 versions of images of a folder and a file. PNG files (may not work with PySimpleGUI27, swap with GIFs)
folder_icon = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABnUlEQVQ4y8WSv2rUQRSFv7vZgJFFsQg2EkWb4AvEJ8hqKVilSmFn3iNvIAp21oIW9haihBRKiqwElMVsIJjNrprsOr/5dyzml3UhEQIWHhjmcpn7zblw4B9lJ8Xag9mlmQb3AJzX3tOX8Tngzg349q7t5xcfzpKGhOFHnjx+9qLTzW8wsmFTL2Gzk7Y2O/k9kCbtwUZbV+Zvo8Md3PALrjoiqsKSR9ljpAJpwOsNtlfXfRvoNU8Arr/NsVo0ry5z4dZN5hoGqEzYDChBOoKwS/vSq0XW3y5NAI/uN1cvLqzQur4MCpBGEEd1PQDfQ74HYR+LfeQOAOYAmgAmbly+dgfid5CHPIKqC74L8RDyGPIYy7+QQjFWa7ICsQ8SpB/IfcJSDVMAJUwJkYDMNOEPIBxA/gnuMyYPijXAI3lMse7FGnIKsIuqrxgRSeXOoYZUCI8pIKW/OHA7kD2YYcpAKgM5ABXk4qSsdJaDOMCsgTIYAlL5TQFTyUIZDmev0N/bnwqnylEBQS45UKnHx/lUlFvA3fo+jwR8ALb47/oNma38cuqiJ9AAAAAASUVORK5CYII='
file_icon = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABU0lEQVQ4y52TzStEURiHn/ecc6XG54JSdlMkNhYWsiILS0lsJaUsLW2Mv8CfIDtr2VtbY4GUEvmIZnKbZsY977Uwt2HcyW1+dTZvt6fn9557BGB+aaNQKBR2ifkbgWR+cX13ubO1svz++niVTA1ArDHDg91UahHFsMxbKWycYsjze4muTsP64vT43v7hSf/A0FgdjQPQWAmco68nB+T+SFSqNUQgcIbN1bn8Z3RwvL22MAvcu8TACFgrpMVZ4aUYcn77BMDkxGgemAGOHIBXxRjBWZMKoCPA2h6qEUSRR2MF6GxUUMUaIUgBCNTnAcm3H2G5YQfgvccYIXAtDH7FoKq/AaqKlbrBj2trFVXfBPAea4SOIIsBeN9kkCwxsNkAqRWy7+B7Z00G3xVc2wZeMSI4S7sVYkSk5Z/4PyBWROqvox3A28PN2cjUwinQC9QyckKALxj4kv2auK0xAAAAAElFTkSuQmCC'
starting_path = sg.PopupGetFolder('Folder to display')
if not starting_path:
sys.exit()
treedata = sg.TreeData() treedata = sg.TreeData()
treedata.Insert("", '_A_', 'A', [1,2,3]) def add_files_in_folder(parent, dirname):
treedata.Insert("", '_B_', 'B', [4,5,6]) files = os.listdir(dirname)
treedata.Insert("_A_", '_A1_', 'A1', ['can','be','anything']) for f in files:
treedata.Insert("", '_C_', 'C', []) fullname = os.path.join(dirname,f)
treedata.Insert("_C_", '_C1_', 'C1', ['or']) if os.path.isdir(fullname): # if it's a folder, add folder and recurse
treedata.Insert("_A_", '_A2_', 'A2', [None, None]) treedata.Insert(parent, fullname, f, values=[], icon=folder_icon)
treedata.Insert("_A1_", '_A3_', 'A30', ['getting deep']) add_files_in_folder(fullname, fullname)
treedata.Insert("_C_", '_C2_', 'C2', ['nothing', 'at', 'all']) else:
for i in range(100): treedata.Insert(parent, fullname, f, values=[os.stat(fullname).st_size], icon=file_icon)
treedata.Insert('_C_', i, i, [])
layout = [[ sg.Text('Tree Test') ], add_files_in_folder('', starting_path)
[ sg.Tree(data=treedata, headings=['col1', 'col2', 'col3'],change_submits=True, auto_size_columns=True, num_rows=10, col0_width=10, key='_TREE_', show_expanded=True),
layout = [[ sg.Text('File and folder browser Test') ],
[ sg.Tree(data=treedata,
headings=['Size', ],
auto_size_columns=True,
num_rows=20,
col0_width=30,
key='_TREE_',
show_expanded=False,
enable_events=True),
], ],
[ sg.Button('Read'), sg.Button('Update')]] [ sg.Button('Ok'), sg.Button('Cancel')]]
window = sg.Window('Tree Element Test').Layout(layout) window = sg.Window('Tree Element Test').Layout(layout)
print(treedata)
while True: # Event Loop while True: # Event Loop
event, values = window.Read() event, values = window.Read()
if event is None: if event in (None, 'Cancel'):
break break
if event == 'Update':
treedata = sg.TreeData()
treedata.Insert("", '_A_', 'A', [1, 2, 3])
treedata.Insert("", '_B_', 'B', [4, 5, 6])
treedata.Insert("_A_", '_A1_', 'A1', ['can', 'be', 'anything'])
treedata.Insert("", '_C_', 'C', [])
treedata.Insert("_C_", '_C1_', 'C1', ['or'])
treedata.Insert("_A_", '_A2_', 'A2', [None, None])
window.FindElement('_TREE_').Update(treedata)
elif event == 'Read':
print(event, values) print(event, values)

View File

@ -56,6 +56,8 @@ else:
So far can interact with the basic Widgets and get button clicks back. Can't yet read which button caused the event. So far can interact with the basic Widgets and get button clicks back. Can't yet read which button caused the event.
""" """
LOGO_BASE64 = b'R0lGODlhIQAgAPcAAAAAADBpmDBqmTFqmjJrmzJsnDNtnTRrmTZtmzZumzRtnTdunDRunTRunjVvnzdwnzhwnjlxnzVwoDZxoTdyojhzozl0ozh0pDp1pjp2pjp2pzx0oj12pD52pTt3qD54pjt4qDx4qDx5qTx5qj16qj57qz57rD58rT98rkB4pkJ7q0J9rEB9rkF+rkB+r0d9qkZ/rEl7o0h8p0x9pk5/p0l+qUB+sEyBrE2Crk2Er0KAsUKAskSCtEeEtUWEtkaGuEiHuEiHukiIu0qKu0mJvEmKvEqLvk2Nv1GErVGFr1SFrVGHslaHsFCItFSIs1COvlaPvFiJsVyRuWCNsWSPsWeQs2SQtGaRtW+Wt2qVuGmZv3GYuHSdv3ievXyfvV2XxGWZwmScx2mfyXafwHikyP9gWP5pYJmdt6GbrqakuamgsayovYClw4Ory4SszI+vyoSv0JGvx5SzzJi0y5m2zp++16C6z6a/05/A2qHC3aXB2K3I3brP4MKxvsLU48LV5c3a5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAhACAAAAj/AP8JHEiwoMGDCA1uoYIFYZmHZhIe9HIggEUBdgo+3FhGIsEqAiyKXDBnIEeOHgHFEMkyQII4/07KTEijpU01MWWiNDhDgM+fNhHg1Llz4BQCBAYoXar0p4ABaHISJXjnQYMIBbJq1YoUKYQ+UnUOVLJBoBUGaCMoMMB2a4EuYWcKlCBnoAMHMv5lacC3bwMGV+LK5cBEIJ0JKQTWkMC4MeM3gk8KZGPhRpTKApFQoDChs2cOAoluHDjmwoUX//wkMX2hgmvXHUKL7kiQSw6BOFjrvvBBtuiETjQI15ABg/EQvqce5JMjhHPnIEB4UJFcLsIlJEiM2L5dBIzq1gv+p2liwkSJ8+hXgN85mqAUFPBPyJffYj1KyQL12HDB3wWL/yxoEdl9+P1Thw4I6mDDggu2MSBt7eUkUB07VGihhW48GJZJtO3RAw8ggmghGQ/+NhAYPqToQ4g8QFGicgMBoeKMPqTxYoEE/aDjjjuecWOEBMExhBBBFFnkD0Cs8WNCeBRBhBBQRvmEfUAi9IURRWRZxJQciuWRQHmEccQRYhgU3pdofhkQADs='
g_time_start = 0 g_time_start = 0
g_time_end = 0 g_time_end = 0
g_time_delta = 0 g_time_delta = 0
@ -1028,8 +1030,7 @@ class Spin(Element):
class Multiline(Element, QWidget): class Multiline(Element, QWidget):
def __init__(self, default_text='', enter_submits=False, disabled=False, autoscroll=False, size=(None, None), def __init__(self, default_text='', enter_submits=False, disabled=False, autoscroll=False, size=(None, None),
auto_size_text=None, background_color=None, text_color=None, change_submits=False, enable_events=False, do_not_clear=False, auto_size_text=None, background_color=None, text_color=None, change_submits=False, enable_events=False, do_not_clear=False,
key=None, focus=False, key=None, focus=False, font=None, pad=None, tooltip=None, visible=True, size_px=(None,None)):
font=None, pad=None, tooltip=None, visible=True, size_px=(None,None)):
''' '''
Multiline Element Multiline Element
:param default_text: :param default_text:
@ -2199,9 +2200,13 @@ class TabGroup(Element):
def Update(self, visible=None): def Update(self, visible=None):
super().Update(self.QT_QTabWidget, visible=visible) super().Update(self.QT_QTabWidget, visible=visible)
return self return self
def QtCallbackStateChanged(self, state):
if self.ChangeSubmits:
element_callback_quit_mainloop(self)
def __del__(self): def __del__(self):
for row in self.Rows: for row in self.Rows:
for element in row: for element in row:
@ -2753,7 +2758,7 @@ class Tree(Element):
class TreeData(object): class TreeData(object):
class Node(object): class Node(object):
def __init__(self, parent, key, text, values, icon): def __init__(self, parent, key, text, values, icon=None):
self.parent = parent self.parent = parent
self.children = [] self.children = []
self.key = key self.key = key
@ -4140,6 +4145,13 @@ def BuildResultsForSubform(form, initialize_only, top_level_form):
if not top_level_form.NonBlocking and not element.do_not_clear and not top_level_form.ReturnKeyboardEvents: if not top_level_form.NonBlocking and not element.do_not_clear and not top_level_form.ReturnKeyboardEvents:
element.QT_TextEdit.setText('') element.QT_TextEdit.setText('')
elif element.Type == ELEM_TYPE_TAB_GROUP: elif element.Type == ELEM_TYPE_TAB_GROUP:
try:
value = element.QT_QTabWidget.getCurrentIndex()
tab_key = element.FindKeyFromTabName(value)
if tab_key is not None:
value = tab_key
except:
value = None
value = 0 value = 0
elif element.Type == ELEM_TYPE_TABLE: elif element.Type == ELEM_TYPE_TABLE:
value = [] value = []
@ -4449,7 +4461,6 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win):
######################### LOOP THROUGH ELEMENTS ON ROW ######################### ######################### LOOP THROUGH ELEMENTS ON ROW #########################
# *********** ------- Loop through ELEMENTS ------- ***********# # *********** ------- Loop through ELEMENTS ------- ***********#
# *********** Make TK Row ***********# # *********** Make TK Row ***********#
tk_row_frame = 000000 #TODO get something to "pack into"
qt_row_layout = QHBoxLayout() qt_row_layout = QHBoxLayout()
for col_num, element in enumerate(flex_row): for col_num, element in enumerate(flex_row):
element.ParentForm = toplevel_win # save the button's parent form object element.ParentForm = toplevel_win # save the button's parent form object
@ -5168,7 +5179,6 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win):
qt_row_layout.addWidget(column_widget) qt_row_layout.addWidget(column_widget)
# ------------------------- Tab element ------------------------- # # ------------------------- Tab element ------------------------- #
elif element_type == ELEM_TYPE_TAB: elif element_type == ELEM_TYPE_TAB:
tab_widget = QWidget() tab_widget = QWidget()
element.QT_QWidget = tab_widget element.QT_QWidget = tab_widget
# tab_widget.setFrameShape(QtWidgets.QFrame.NoFrame) # tab_widget.setFrameShape(QtWidgets.QFrame.NoFrame)
@ -5221,7 +5231,7 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win):
element.QT_QTabWidget.setVisible(False) element.QT_QTabWidget.setVisible(False)
if element.ChangeSubmits: if element.ChangeSubmits:
pass element.QT_QTabWidget.currentChanged.connect(element.QtCallbackStateChanged)
# ------------------------- SLIDER element ------------------------- # # ------------------------- SLIDER element ------------------------- #
elif element_type == ELEM_TYPE_INPUT_SLIDER: elif element_type == ELEM_TYPE_INPUT_SLIDER:
element.QT_Slider = QSlider() element.QT_Slider = QSlider()
@ -5381,19 +5391,28 @@ def PackFormIntoFrame(window, containing_frame, toplevel_win):
except: except:
width = element.DefaultColumnWidth width = element.DefaultColumnWidth
# treeview.column(heading, width=width * CharWidthInPixels(), anchor=anchor) # treeview.column(heading, width=width * CharWidthInPixels(), anchor=anchor)
def add_treeview_data(node, widget): def add_treeview_data(node, widget):
# print(f'Inserting {node.key} under parent {node.parent}') # print(f'Inserting {node.key} under parent {node.parent}')
child = QTreeWidgetItem(widget) child = QTreeWidgetItem(widget)
if node.key != '': if node.key != '':
child.setText(0, str(node.text)) child.setText(0, str(node.text))
# child.setData(0,0,node.values) # child.setData(0,0,node.values)
if node.icon is not None: if type(node.icon) is bytes:
ba = QtCore.QByteArray.fromBase64(node.icon)
pixmap = QtGui.QPixmap()
pixmap.loadFromData(ba)
qicon = QIcon(pixmap)
child.setIcon(0, qicon)
elif node.icon is not None:
qicon = QIcon(node.icon) qicon = QIcon(node.icon)
child.setIcon(0, qicon) child.setIcon(0, qicon)
for node in node.children: for node in node.children:
add_treeview_data(node, child) add_treeview_data(node, child)
# for node in element.TreeData.root_node.children:
# add_treeview_data(node, element.QT_QTreeWidget)
add_treeview_data(element.TreeData.root_node, element.QT_QTreeWidget) add_treeview_data(element.TreeData.root_node, element.QT_QTreeWidget)
style = 'QTreeWidget {' style = 'QTreeWidget {'
@ -5538,11 +5557,9 @@ def StartupTK(window):
window.QT_QMainWindow.setWindowOpacity(window.AlphaChannel) window.QT_QMainWindow.setWindowOpacity(window.AlphaChannel)
if window.WindowIcon is not None: if window.WindowIcon is not None:
window.QT_QMainWindow.setWindowIcon(QtGui.QIcon(window.WindowIcon)) window.QT_QMainWindow.setWindowIcon(QtGui.QIcon(window.WindowIcon))
if window.DisableMinimize: if window.DisableMinimize:
window.QT_QMainWindow.setWindowFlags(window.QT_QMainWindow.windowFlags()&~Qt.WindowMinimizeButtonHint) window.QT_QMainWindow.setWindowFlags(window.QT_QMainWindow.windowFlags()&~Qt.WindowMinimizeButtonHint)
window.QT_QMainWindow.setWindowFlags(window.QT_QMainWindow.windowFlags()&~Qt.WindowMaximizeButtonHint) window.QT_QMainWindow.setWindowFlags(window.QT_QMainWindow.windowFlags()&~Qt.WindowMaximizeButtonHint)
if window.DisableClose: if window.DisableClose:
window.QT_QMainWindow.setWindowFlags(window.QT_QMainWindow.windowFlags()&~Qt.WindowCloseButtonHint) window.QT_QMainWindow.setWindowFlags(window.QT_QMainWindow.windowFlags()&~Qt.WindowCloseButtonHint)