Skip to content

Commit bc6fcad

Browse files
committed
fix #16
1 parent 2ab39b8 commit bc6fcad

File tree

11 files changed

+324
-49
lines changed

11 files changed

+324
-49
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
All major and minor version changes will be documented in this file. Details of
44
patch-level version changes can be found in [commit messages](../../commits/master).
55

6+
## 2025 - 2025/02/18
7+
8+
- fpg write to file picker #24
9+
- dpg add file picker #16
10+
611
## 2024.3 - 2024/10/05
712

813
- Code improvements

cli2gui/application/application.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,15 @@ def run(buildSpec: types.FullBuildSpec) -> Any:
2626
# Set the theme
2727
theme = helpers.get_base24_theme(buildSpec.theme, buildSpec.darkTheme)
2828

29+
buildSpec.gui = buildSpec.gui.replace("pysimplegui", "psg").replace("freesimplegui", "fsg")
30+
2931
if buildSpec.gui in [
30-
"pysimplegui",
31-
"pysimpleguiqt",
32-
"pysimpleguiweb",
33-
"freesimplegui",
32+
"psg",
33+
"psgqt",
34+
"psgweb",
35+
"fsg",
36+
# "fsgqt", # cannot test on windows
37+
# "fsgweb", # bug in remi prevents this from working
3438
]:
3539
gui_wrapper = PySimpleGUIWrapper
3640
else:

cli2gui/gui/dearpygui_wrapper.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,45 @@ def _helpIntCounterWidget(self, item: Item) -> None:
7171
)
7272

7373
def _helpFileWidget(self, item: Item) -> None:
74+
"""Create a UI element with an input text field and a file picker."""
75+
76+
def file_picker_callback(_sender: str, app_data: dict[str, Any]) -> None:
77+
"""Update the input text field with the selected file path."""
78+
79+
file_path = ""
80+
# User may have selected and edited, or just written a name
81+
user_input_path = Path(app_data.get("file_path_name", ""))
82+
83+
# Get the selection if possible
84+
selected_path = Path(next(iter(app_data.get("selections", {}).values()), ""))
85+
86+
if user_input_path.stem == selected_path.stem:
87+
file_path = selected_path
88+
# User may have selected and edited, or just written a name
89+
else:
90+
file_path = user_input_path.stem + Path(item.default or "").suffix
91+
dpg.set_value(item.dest, str(file_path))
92+
7493
with dpg.group(horizontal=False):
7594
self._helpText(item)
95+
7696
dpg.add_input_text(tag=item.dest, default_value=(item.default or ""))
7797

98+
dpg.add_button(
99+
label="Browse", callback=lambda: dpg.show_item(f"{item.dest}_file_dialog")
100+
)
101+
102+
with dpg.file_dialog(
103+
directory_selector=False,
104+
show=False,
105+
callback=file_picker_callback,
106+
id=f"{item.dest}_file_dialog",
107+
width=650,
108+
height=400,
109+
file_count=1,
110+
):
111+
dpg.add_file_extension(".*", color=hex_to_rgb(self.base24Theme[13]))
112+
78113
def _helpDropdownWidget(self, item: Item) -> None:
79114
with dpg.group(horizontal=False):
80115
self._helpText(item)
@@ -305,8 +340,17 @@ def main(
305340

306341
# Define "Run" and "Exit" buttons
307342
def _run_callback() -> None:
308-
_items = [item for item in items if item.dest]
309-
myd = {f"{item.dest}{SEP}{item.type}": dpg.get_value(item.dest) for item in _items}
343+
_items: list[Item] = [item for item in items if item.dest]
344+
myd = {}
345+
for item in _items:
346+
value = dpg.get_value(item.dest)
347+
key = f"{item.dest}{SEP}{item.type}"
348+
if item.type in [ItemType.File, ItemType.FileWrite]:
349+
prop = item.additional_properties
350+
key += f";{prop.get('file_mode')};{prop.get('file_encoding')}"
351+
352+
myd[key] = value
353+
310354
run_callback(myd)
311355

312356
def close_dpg() -> None:

cli2gui/gui/pysimplegui_wrapper.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ class PySimpleGUIWrapper(AbstractGUI):
1919
def __init__(self, base24Theme: list[str], psg_lib: str) -> None:
2020
super().__init__()
2121

22-
if psg_lib == "pysimplegui":
22+
if psg_lib == "psg":
2323
import PySimpleGUI as gui_lib
24-
elif psg_lib == "pysimpleguiqt":
24+
elif psg_lib == "psgqt":
2525
import PySimpleGUIQt as gui_lib
26-
elif psg_lib == "pysimpleguiweb":
26+
elif psg_lib == "psgweb":
2727
import PySimpleGUIWeb as gui_lib
28+
elif psg_lib == "fsgqt":
29+
import FreeSimpleGUIQt as gui_lib
30+
elif psg_lib == "fsgweb":
31+
import FreeSimpleGUIWeb as gui_lib
2832
else:
2933
import FreeSimpleGUI as gui_lib
3034

@@ -40,7 +44,7 @@ def __init__(self, base24Theme: list[str], psg_lib: str) -> None:
4044
"text_size": 11,
4145
}
4246

43-
if psg_lib not in ["pysimplegui", "freesimplegui"]:
47+
if psg_lib not in ["psg", "fsg"]:
4448
self.sizes = {
4549
"title_size": 18,
4650
"label_size": (600, None),
@@ -316,10 +320,10 @@ def generatePopup(
316320
Window: A PySimpleGui Window
317321
318322
"""
319-
maxLines = 30 if self.psg_lib == "pysimpleguiqt" else 200
323+
maxLines = 30 if self.psg_lib == "psgqt" else 200
320324
popupText = helpers.read_file(buildSpec.menu[values[0]], maxLines)
321325

322-
if self.psg_lib == "pysimplegui":
326+
if self.psg_lib in ["psg", "fsg"]:
323327
popupLayout = [
324328
self._title(values[0]),
325329
[
@@ -425,8 +429,8 @@ def createLayout(
425429
]
426430
)
427431
if len(argConstruct) > buildSpec.max_args_shown and self.psg_lib in (
428-
"pysimplegui",
429-
"freesimplegui",
432+
"psg",
433+
"fsg",
430434
):
431435
layout.append(
432436
[

documentation/reference/cli2gui/gui/dearpygui_wrapper.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
- [DearPyGuiWrapper](#dearpyguiwrapper)
88
- [DearPyGuiWrapper](#dearpyguiwrapper-1)
9+
- [DearPyGuiWrapper()._helpFileWidget](#dearpyguiwrapper()_helpfilewidget)
910
- [DearPyGuiWrapper().addItemsAndGroups](#dearpyguiwrapper()additemsandgroups)
1011
- [DearPyGuiWrapper().addWidgetFromItem](#dearpyguiwrapper()addwidgetfromitem)
1112
- [DearPyGuiWrapper().main](#dearpyguiwrapper()main)
@@ -29,9 +30,25 @@ class DearPyGuiWrapper(AbstractGUI):
2930

3031
- [AbstractGUI](./abstract_gui.md#abstractgui)
3132

33+
### DearPyGuiWrapper()._helpFileWidget
34+
35+
[Show source in dearpygui_wrapper.py:73](../../../../cli2gui/gui/dearpygui_wrapper.py#L73)
36+
37+
Create a UI element with an input text field and a file picker.
38+
39+
#### Signature
40+
41+
```python
42+
def _helpFileWidget(self, item: Item) -> None: ...
43+
```
44+
45+
#### See also
46+
47+
- [Item](../types.md#item)
48+
3249
### DearPyGuiWrapper().addItemsAndGroups
3350

34-
[Show source in dearpygui_wrapper.py:105](../../../../cli2gui/gui/dearpygui_wrapper.py#L105)
51+
[Show source in dearpygui_wrapper.py:140](../../../../cli2gui/gui/dearpygui_wrapper.py#L140)
3552

3653
Items and groups and return a list of these so we can get values from the dpg widgets.
3754

@@ -57,7 +74,7 @@ def addItemsAndGroups(self, section: Group) -> list[Item]: ...
5774

5875
### DearPyGuiWrapper().addWidgetFromItem
5976

60-
[Show source in dearpygui_wrapper.py:83](../../../../cli2gui/gui/dearpygui_wrapper.py#L83)
77+
[Show source in dearpygui_wrapper.py:118](../../../../cli2gui/gui/dearpygui_wrapper.py#L118)
6178

6279
Select a widget based on the item type.
6380

@@ -77,7 +94,7 @@ def addWidgetFromItem(self, item: Item) -> None: ...
7794

7895
### DearPyGuiWrapper().main
7996

80-
[Show source in dearpygui_wrapper.py:149](../../../../cli2gui/gui/dearpygui_wrapper.py#L149)
97+
[Show source in dearpygui_wrapper.py:184](../../../../cli2gui/gui/dearpygui_wrapper.py#L184)
8198

8299
Run the gui (dpg) with a given buildSpec, quit_callback, and run_callback.
83100

@@ -109,7 +126,7 @@ def main(
109126

110127
### DearPyGuiWrapper().open_menu_item
111128

112-
[Show source in dearpygui_wrapper.py:135](../../../../cli2gui/gui/dearpygui_wrapper.py#L135)
129+
[Show source in dearpygui_wrapper.py:170](../../../../cli2gui/gui/dearpygui_wrapper.py#L170)
113130

114131
Open a menu item.
115132

0 commit comments

Comments
 (0)