commit
c620282650
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue