Skip to content

Commit 6922339

Browse files
author
Shengjie Xu
committed
[GUI/PySide6] Initial draft for main input
1 parent e91955a commit 6922339

9 files changed

+520
-37
lines changed

src/preppipe_gui_pyside6/componentwidgets/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import os
2+
import typing
3+
from PySide6.QtWidgets import *
4+
from PySide6.QtCore import *
5+
from PySide6.QtGui import *
6+
from ..forms.generated.ui_filelistinputwidget import Ui_FileListInputWidget
7+
from preppipe.language import *
8+
from ..translatablewidgetinterface import *
9+
10+
class FileListInputWidget(QWidget, TranslatableWidgetInterface):
11+
listChanged = Signal()
12+
13+
ui : Ui_FileListInputWidget
14+
isDirectoryMode : bool
15+
isExistingOnly : bool
16+
verifyCB : typing.Callable[[str], bool] | None
17+
fieldName : Translatable | str
18+
filter : Translatable | str
19+
lastAddedPath : str
20+
21+
TR_gui_filelistinputwidget = TranslationDomain("gui_filelistinputwidget")
22+
_tr_add = TR_gui_filelistinputwidget.tr("add",
23+
en="Add",
24+
zh_cn="添加",
25+
zh_hk="添加",
26+
)
27+
_tr_remove = TR_gui_filelistinputwidget.tr("remove",
28+
en="Remove",
29+
zh_cn="删除",
30+
zh_hk="刪除",
31+
)
32+
_tr_move_up = TR_gui_filelistinputwidget.tr("move_up",
33+
en="Move Up",
34+
zh_cn="上移",
35+
zh_hk="上移",
36+
)
37+
_tr_move_down = TR_gui_filelistinputwidget.tr("move_down",
38+
en="Move Down",
39+
zh_cn="下移",
40+
zh_hk="下移",
41+
)
42+
43+
def __init__(self, parent : QWidget | None = None):
44+
super(FileListInputWidget, self).__init__(parent)
45+
self.ui = Ui_FileListInputWidget()
46+
self.ui.setupUi(self)
47+
self.isDirectoryMode = False
48+
self.isExistingOnly = False
49+
self.verifyCB = None
50+
self.fieldName = ""
51+
self.filter = ""
52+
self.lastAddedPath = ""
53+
54+
self.bind_text(self.ui.addButton.setText, self._tr_add)
55+
self.bind_text(self.ui.removeButton.setText, self._tr_remove)
56+
self.bind_text(self.ui.moveUpButton.setText, self._tr_move_up)
57+
self.bind_text(self.ui.moveDownButton.setText, self._tr_move_down)
58+
59+
self.ui.listWidget.itemChanged.connect(lambda: self.listChanged.emit())
60+
self.ui.addButton.clicked.connect(self.itemAdd)
61+
self.ui.removeButton.clicked.connect(self.itemRemove)
62+
self.ui.moveUpButton.clicked.connect(self.itemMoveUp)
63+
self.ui.moveDownButton.clicked.connect(self.itemMoveDown)
64+
self.setAcceptDrops(True)
65+
66+
def setDirectoryMode(self, v: bool):
67+
self.isDirectoryMode = v
68+
if self.verifyCB is None:
69+
self.verifyCB = (lambda path: os.path.isdir(path)) if v else (lambda path: os.path.isfile(path))
70+
71+
def setVerifyCallBack(self, cb):
72+
"""Set a callback function that verifies a path. The function should accept a string and return a boolean."""
73+
self.verifyCB = cb
74+
75+
def setExistingOnly(self, v: bool):
76+
self.isExistingOnly = v
77+
78+
def setFieldName(self, name: Translatable | str):
79+
self.fieldName = name
80+
if isinstance(name, Translatable):
81+
self.bind_text(self.ui.label.setText, name)
82+
else:
83+
self.ui.label.setText(name)
84+
85+
def setFilter(self, filter_str: Translatable | str):
86+
self.filter = filter_str
87+
88+
def getCurrentList(self):
89+
results = []
90+
for i in range(self.ui.listWidget.count()):
91+
item = self.ui.listWidget.item(i)
92+
results.append(item.text())
93+
return results
94+
95+
def dragEnterEvent(self, e: QDragEnterEvent):
96+
if e.mimeData().hasUrls():
97+
path = e.mimeData().urls()[0].toLocalFile()
98+
if not self.verifyCB or self.verifyCB(path):
99+
e.acceptProposedAction()
100+
return
101+
super().dragEnterEvent(e)
102+
103+
def dropEvent(self, event: QDropEvent):
104+
for url in event.mimeData().urls():
105+
path = url.toLocalFile()
106+
if not self.verifyCB or self.verifyCB(path):
107+
self.addPath(path)
108+
event.acceptProposedAction()
109+
110+
@Slot(str)
111+
def addPath(self, path: str):
112+
# Prevent duplicates
113+
for i in range(self.ui.listWidget.count()):
114+
if self.ui.listWidget.item(i).text() == path:
115+
return
116+
newItem = QListWidgetItem(path)
117+
newItem.setToolTip(path)
118+
self.ui.listWidget.addItem(newItem)
119+
self.lastAddedPath = path
120+
self.listChanged.emit()
121+
122+
@Slot()
123+
def itemMoveUp(self):
124+
curRow = self.ui.listWidget.currentRow()
125+
if curRow > 0:
126+
item = self.ui.listWidget.takeItem(curRow)
127+
self.ui.listWidget.insertItem(curRow - 1, item)
128+
self.ui.listWidget.setCurrentRow(curRow - 1)
129+
self.listChanged.emit()
130+
131+
@Slot()
132+
def itemMoveDown(self):
133+
curRow = self.ui.listWidget.currentRow()
134+
if curRow >= 0 and curRow + 1 < self.ui.listWidget.count():
135+
item = self.ui.listWidget.takeItem(curRow)
136+
self.ui.listWidget.insertItem(curRow + 1, item)
137+
self.ui.listWidget.setCurrentRow(curRow + 1)
138+
self.listChanged.emit()
139+
140+
_tr_select_dialog_title = TR_gui_filelistinputwidget.tr("select_dialog_title",
141+
en="Please select {field}",
142+
zh_cn="请选择{field}",
143+
zh_hk="請選擇{field}",
144+
)
145+
146+
@Slot()
147+
def itemAdd(self):
148+
dialogTitle = self._tr_select_dialog_title.format(field=str(self.fieldName))
149+
initialDir = self.lastAddedPath if self.lastAddedPath else ""
150+
dialog = QFileDialog(self, dialogTitle, initialDir, str(self.filter))
151+
if self.isDirectoryMode:
152+
dialog.setFileMode(QFileDialog.Directory)
153+
dialog.setOption(QFileDialog.ShowDirsOnly, True)
154+
else:
155+
dialog.setFileMode(QFileDialog.ExistingFile if self.isExistingOnly else QFileDialog.AnyFile)
156+
dialog.fileSelected.connect(self.addPath)
157+
dialog.show()
158+
159+
@Slot()
160+
def itemRemove(self):
161+
curRow = self.ui.listWidget.currentRow()
162+
if curRow >= 0:
163+
item = self.ui.listWidget.takeItem(curRow)
164+
del item
165+
self.listChanged.emit()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>FileListInputWidget</class>
4+
<widget class="QWidget" name="FileListInputWidget">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>429</width>
10+
<height>263</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Form</string>
15+
</property>
16+
<layout class="QVBoxLayout" name="verticalLayout">
17+
<property name="leftMargin">
18+
<number>0</number>
19+
</property>
20+
<property name="topMargin">
21+
<number>0</number>
22+
</property>
23+
<property name="rightMargin">
24+
<number>0</number>
25+
</property>
26+
<property name="bottomMargin">
27+
<number>0</number>
28+
</property>
29+
<item>
30+
<layout class="QHBoxLayout" name="horizontalLayout">
31+
<item>
32+
<widget class="QLabel" name="label">
33+
<property name="sizePolicy">
34+
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
35+
<horstretch>0</horstretch>
36+
<verstretch>0</verstretch>
37+
</sizepolicy>
38+
</property>
39+
<property name="text">
40+
<string>输入名</string>
41+
</property>
42+
</widget>
43+
</item>
44+
<item>
45+
<widget class="QPushButton" name="addButton">
46+
<property name="sizePolicy">
47+
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
48+
<horstretch>0</horstretch>
49+
<verstretch>0</verstretch>
50+
</sizepolicy>
51+
</property>
52+
<property name="text">
53+
<string>添加</string>
54+
</property>
55+
</widget>
56+
</item>
57+
<item>
58+
<widget class="QPushButton" name="removeButton">
59+
<property name="sizePolicy">
60+
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
61+
<horstretch>0</horstretch>
62+
<verstretch>0</verstretch>
63+
</sizepolicy>
64+
</property>
65+
<property name="text">
66+
<string>删除</string>
67+
</property>
68+
</widget>
69+
</item>
70+
<item>
71+
<widget class="QPushButton" name="moveUpButton">
72+
<property name="sizePolicy">
73+
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
74+
<horstretch>0</horstretch>
75+
<verstretch>0</verstretch>
76+
</sizepolicy>
77+
</property>
78+
<property name="text">
79+
<string>上移</string>
80+
</property>
81+
</widget>
82+
</item>
83+
<item>
84+
<widget class="QPushButton" name="moveDownButton">
85+
<property name="sizePolicy">
86+
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
87+
<horstretch>0</horstretch>
88+
<verstretch>0</verstretch>
89+
</sizepolicy>
90+
</property>
91+
<property name="text">
92+
<string>下移</string>
93+
</property>
94+
</widget>
95+
</item>
96+
</layout>
97+
</item>
98+
<item>
99+
<widget class="QListWidget" name="listWidget">
100+
<property name="verticalScrollBarPolicy">
101+
<enum>Qt::ScrollBarAlwaysOn</enum>
102+
</property>
103+
<property name="dragEnabled">
104+
<bool>true</bool>
105+
</property>
106+
<property name="dragDropMode">
107+
<enum>QAbstractItemView::InternalMove</enum>
108+
</property>
109+
<property name="selectionBehavior">
110+
<enum>QAbstractItemView::SelectRows</enum>
111+
</property>
112+
</widget>
113+
</item>
114+
</layout>
115+
</widget>
116+
<resources/>
117+
<connections/>
118+
</ui>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>MainInputWidget</class>
4+
<widget class="QWidget" name="MainInputWidget">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>666</width>
10+
<height>406</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Form</string>
15+
</property>
16+
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
17+
<property name="leftMargin">
18+
<number>0</number>
19+
</property>
20+
<property name="topMargin">
21+
<number>0</number>
22+
</property>
23+
<property name="rightMargin">
24+
<number>0</number>
25+
</property>
26+
<property name="bottomMargin">
27+
<number>0</number>
28+
</property>
29+
<item>
30+
<widget class="QGroupBox" name="inputGroupBox">
31+
<property name="title">
32+
<string>Input</string>
33+
</property>
34+
</widget>
35+
</item>
36+
<item>
37+
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
38+
<item>
39+
<widget class="QGroupBox" name="analysisGroupBox">
40+
<property name="title">
41+
<string>Analysis</string>
42+
</property>
43+
</widget>
44+
</item>
45+
<item>
46+
<widget class="QGroupBox" name="exportGroupBox">
47+
<property name="title">
48+
<string>GroupBox</string>
49+
</property>
50+
</widget>
51+
</item>
52+
</layout>
53+
</item>
54+
</layout>
55+
</widget>
56+
<resources/>
57+
<connections/>
58+
</ui>

src/preppipe_gui_pyside6/mainwindowinterface.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,25 @@ def requestOpenDocument(self, relpath : str | None) -> None:
1919
raise NotImplementedError("Subclasses must implement the requestOpenDocument() method.")
2020

2121
def handleLanguageChange(self) -> None:
22-
raise NotImplementedError("Subclasses must implement the handleLanguageChange() method.")
22+
raise NotImplementedError("Subclasses must implement the handleLanguageChange() method.")
23+
24+
tr_toolname_maininput = TR_gui_mainwindow.tr("toolname_maininput",
25+
en="Main Pipeline Entry",
26+
zh_cn="主管线入口",
27+
zh_hk="主管線入口",
28+
)
29+
tr_toolname_analysis = TR_gui_mainwindow.tr("toolname_analysis",
30+
en="Analysis Tools",
31+
zh_cn="分析工具",
32+
zh_hk="分析工具",
33+
)
34+
tr_toolname_export_renpy = TR_gui_mainwindow.tr("toolname_export_renpy",
35+
en="Ren'Py Export",
36+
zh_cn="Ren'Py 导出",
37+
zh_hk="Ren'Py 導出",
38+
)
39+
tr_toolname_export_webgal = TR_gui_mainwindow.tr("toolname_export_webgal",
40+
en="WebGal Export",
41+
zh_cn="WebGal 导出",
42+
zh_hk="WebGal 導出",
43+
)

src/preppipe_gui_pyside6/navigatorwidget.py

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from .mainwindowinterface import *
1212
from .toolwidgets.imagepack import *
1313
from .toolwidgets.setting import *
14+
from .toolwidgets.maininput import *
1415

1516
class ToolNode:
1617
info : ToolWidgetInfo | None
@@ -22,6 +23,7 @@ class ToolNode:
2223
]
2324
NAVIGATION_LIST : typing.ClassVar[list] = [
2425
SettingWidget,
26+
MainInputWidget,
2527
ImagePackBackgroundTool,
2628
]
2729

0 commit comments

Comments
 (0)