cellects 0.1.3__py3-none-any.whl → 0.2.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cellects/__main__.py +65 -25
- cellects/config/all_vars_dict.py +18 -17
- cellects/core/cellects_threads.py +1034 -396
- cellects/core/motion_analysis.py +1664 -2010
- cellects/core/one_image_analysis.py +1082 -1061
- cellects/core/program_organizer.py +1687 -1316
- cellects/core/script_based_run.py +80 -76
- cellects/gui/advanced_parameters.py +365 -326
- cellects/gui/cellects.py +102 -91
- cellects/gui/custom_widgets.py +4 -3
- cellects/gui/first_window.py +226 -104
- cellects/gui/if_several_folders_window.py +117 -68
- cellects/gui/image_analysis_window.py +841 -450
- cellects/gui/required_output.py +100 -56
- cellects/gui/ui_strings.py +840 -0
- cellects/gui/video_analysis_window.py +317 -135
- cellects/image_analysis/cell_leaving_detection.py +64 -4
- cellects/image_analysis/image_segmentation.py +451 -22
- cellects/image_analysis/morphological_operations.py +2166 -1635
- cellects/image_analysis/network_functions.py +616 -253
- cellects/image_analysis/one_image_analysis_threads.py +94 -153
- cellects/image_analysis/oscillations_functions.py +131 -0
- cellects/image_analysis/progressively_add_distant_shapes.py +2 -3
- cellects/image_analysis/shape_descriptors.py +517 -466
- cellects/utils/formulas.py +169 -6
- cellects/utils/load_display_save.py +362 -105
- cellects/utils/utilitarian.py +86 -9
- cellects-0.2.7.dist-info/LICENSE +675 -0
- cellects-0.2.7.dist-info/METADATA +829 -0
- cellects-0.2.7.dist-info/RECORD +44 -0
- cellects/core/one_video_per_blob.py +0 -540
- cellects/image_analysis/cluster_flux_study.py +0 -102
- cellects-0.1.3.dist-info/LICENSE.odt +0 -0
- cellects-0.1.3.dist-info/METADATA +0 -176
- cellects-0.1.3.dist-info/RECORD +0 -44
- {cellects-0.1.3.dist-info → cellects-0.2.7.dist-info}/WHEEL +0 -0
- {cellects-0.1.3.dist-info → cellects-0.2.7.dist-info}/entry_points.txt +0 -0
- {cellects-0.1.3.dist-info → cellects-0.2.7.dist-info}/top_level.txt +0 -0
|
@@ -1,93 +1,124 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
|
|
2
|
+
"""GUI window for selecting folders when multiple options exist in Cellects analysis workflow.
|
|
3
|
+
|
|
4
|
+
This module implements a second-stage GUI dialog that appears when multiple experiment folders are available.
|
|
5
|
+
It provides an interface for folder selection via checkboxes and table visualization, with navigation controls to
|
|
6
|
+
proceed to image analysis or return to prior steps. Includes thread-safe background operations for loading data without
|
|
7
|
+
freezing the UI.
|
|
8
|
+
|
|
9
|
+
Main Components
|
|
10
|
+
IfSeveralFoldersWindow : QWidget subclass managing folder selection and analysis workflow navigation
|
|
11
|
+
"""
|
|
4
12
|
import logging
|
|
5
|
-
|
|
13
|
+
import numpy as np
|
|
6
14
|
from PySide6 import QtWidgets, QtCore
|
|
7
|
-
|
|
8
15
|
from cellects.core.cellects_threads import LoadFirstFolderIfSeveralThread
|
|
9
|
-
from cellects.gui.custom_widgets import (
|
|
10
|
-
|
|
16
|
+
from cellects.gui.custom_widgets import (WindowType, PButton, FixedText)
|
|
17
|
+
from cellects.gui.ui_strings import MF, VAW
|
|
11
18
|
|
|
12
19
|
|
|
13
20
|
class IfSeveralFoldersWindow(WindowType):
|
|
21
|
+
"""
|
|
22
|
+
Second window of the Cellects GUI, only appears when there are multiple folders.
|
|
23
|
+
"""
|
|
14
24
|
def __init__(self, parent, night_mode):
|
|
25
|
+
"""
|
|
26
|
+
Initialize the IfSeveralFolders window with a parent widget and night mode setting.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
parent : QWidget
|
|
31
|
+
The parent widget to which this window will be attached.
|
|
32
|
+
night_mode : bool
|
|
33
|
+
A boolean indicating whether the night mode should be enabled.
|
|
34
|
+
|
|
35
|
+
Examples
|
|
36
|
+
--------
|
|
37
|
+
>>> from PySide6 import QtWidgets
|
|
38
|
+
>>> from cellects.gui.cellects import CellectsMainWidget
|
|
39
|
+
>>> from cellects.gui.if_several_folders_window import IfSeveralFoldersWindow
|
|
40
|
+
>>> import sys
|
|
41
|
+
>>> app = QtWidgets.QApplication([])
|
|
42
|
+
>>> parent = CellectsMainWidget()
|
|
43
|
+
>>> session = IfSeveralFoldersWindow(parent, False)
|
|
44
|
+
>>> session.true_init()
|
|
45
|
+
>>> parent.insertWidget(0, session)
|
|
46
|
+
>>> parent.show()
|
|
47
|
+
>>> sys.exit(app.exec())
|
|
48
|
+
"""
|
|
15
49
|
super().__init__(parent, night_mode)
|
|
16
50
|
self.setParent(parent)
|
|
17
51
|
|
|
18
52
|
def true_init(self):
|
|
53
|
+
"""
|
|
54
|
+
Initialize the IfSeveralFoldersWindow with UI components and settings.
|
|
55
|
+
|
|
56
|
+
Extended Description
|
|
57
|
+
--------------------
|
|
58
|
+
This method sets up the user interface for the IfSeveralFoldersWindow,
|
|
59
|
+
including labels, a table widget for folders and sample sizes, checkboxes,
|
|
60
|
+
buttons for video analysis and running tasks directly, and navigation
|
|
61
|
+
buttons for previous and next steps. The window supports multiple folder
|
|
62
|
+
selection and provides a means to control the analysis process.
|
|
63
|
+
|
|
64
|
+
Notes
|
|
65
|
+
-----
|
|
66
|
+
This method assumes that the parent widget has a 'po' attribute with specific settings and variables.
|
|
67
|
+
"""
|
|
19
68
|
logging.info("Initialize IfSeveralFoldersWindow")
|
|
20
69
|
self.thread = {}
|
|
21
70
|
self.thread["LoadFirstFolderIfSeveral"] = LoadFirstFolderIfSeveralThread(self.parent())
|
|
22
71
|
self.next_clicked_once:bool = False
|
|
23
72
|
self.layout = QtWidgets.QVBoxLayout()
|
|
24
|
-
# self.layout.setAlignment(QtCore.Qt.AlignLeading)
|
|
25
|
-
# self.layout.setGeometry(QtCore.QRect(9, 9, 2 * self.parent().screen_width // 3, 2 * self.parent().screen_height // 3))
|
|
26
73
|
|
|
27
74
|
self.title_label = FixedText('Select folders to analyze', police=30, night_mode=self.parent().po.all['night_mode'])
|
|
28
75
|
self.title_label.setAlignment(QtCore.Qt.AlignHCenter)
|
|
29
|
-
# self.layout.addWidget(self.title_label, 0, 0, 1, - 1)
|
|
30
76
|
self.layout.addWidget(self.title_label)
|
|
31
77
|
self.layout.addItem(self.vertical_space)
|
|
32
78
|
|
|
33
79
|
# 1) add a check box allowing to select every folders
|
|
34
80
|
self.cb_layout = QtWidgets.QHBoxLayout()
|
|
35
81
|
self.cb_widget = QtWidgets.QWidget()
|
|
36
|
-
self.cb_label = FixedText(
|
|
82
|
+
self.cb_label = FixedText(MF["Check_to_select_all_folders"]["label"] + ':', tip=MF["Check_to_select_all_folders"]["tips"], night_mode=self.parent().po.all['night_mode'])
|
|
37
83
|
self.cb = QtWidgets.QCheckBox()
|
|
38
84
|
self.cb.setChecked(True)
|
|
39
85
|
self.cb.clicked.connect(self.checked)
|
|
40
|
-
# self.cb.stateChanged.connect(self.checked)
|
|
41
|
-
|
|
42
|
-
# self.layout.addWidget(self.cb_label, 1, 0, 1, 1)
|
|
43
|
-
# self.layout.addWidget(self.cb, 1, 1, 1, 1)
|
|
44
86
|
self.cb_layout.addWidget(self.cb_label)
|
|
45
87
|
self.cb_layout.addWidget(self.cb)
|
|
46
88
|
self.cb_layout.addItem(self.horizontal_space)
|
|
47
89
|
self.cb_widget.setLayout(self.cb_layout)
|
|
48
90
|
self.layout.addWidget(self.cb_widget)
|
|
49
|
-
# spacerItem = QtWidgets.QSpacerItem(0, 1, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding)
|
|
50
|
-
# self.layout.addItem(spacerItem, 1, 2, 1, 3)
|
|
51
91
|
|
|
52
92
|
# 2) Create a folder list and sample number per folder
|
|
53
93
|
self.tableau = QtWidgets.QTableWidget() # Scroll Area which contains the widgets, set as the centralWidget
|
|
54
94
|
self.tableau.setColumnCount(2)
|
|
55
95
|
self.tableau.setRowCount(len(self.parent().po.all['folder_list']))
|
|
56
96
|
self.tableau.setHorizontalHeaderLabels(['Folders', 'Sample size'])
|
|
57
|
-
# if len(self.parent().po.all['sample_number_per_folder']) < 2:
|
|
58
97
|
self.parent().po.all['sample_number_per_folder'] = np.repeat(int(self.parent().po.all['first_folder_sample_number']), self.parent().po.all['folder_number'])
|
|
59
98
|
|
|
60
99
|
for i, folder in enumerate(self.parent().po.all['folder_list']):
|
|
61
100
|
self.tableau.setItem(i, 0, QtWidgets.QTableWidgetItem(folder))
|
|
62
101
|
self.tableau.setItem(i, 1, QtWidgets.QTableWidgetItem(str(self.parent().po.all['sample_number_per_folder'][i])))
|
|
63
|
-
# if isinstance(self.parent().po.all['sample_number_per_folder'], int):
|
|
64
|
-
# self.tableau.setItem(i, 1, QtWidgets.QTableWidgetItem(str(self.parent().po.all['sample_number_per_folder'])))
|
|
65
|
-
# else:
|
|
66
|
-
# self.tableau.setItem(i, 1, QtWidgets.QTableWidgetItem(str(self.parent().po.all['sample_number_per_folder'][i])))
|
|
67
102
|
self.tableau.horizontalHeader().setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
|
|
68
103
|
self.tableau.horizontalHeader().setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
|
|
69
104
|
self.tableau.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
|
70
105
|
self.tableau.selectAll()
|
|
71
106
|
self.tableau.itemSelectionChanged.connect(self.item_selection_changed)
|
|
72
107
|
|
|
73
|
-
# self.tableau.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
|
74
108
|
self.tableau.setShowGrid(False)
|
|
75
109
|
self.tableau.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
|
76
110
|
self.tableau.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
77
111
|
self.tableau.horizontalHeader().hide()
|
|
78
112
|
self.tableau.verticalHeader().hide()
|
|
79
|
-
# self.layout.addWidget(self.tableau, 2, 0, 1, 1)
|
|
80
113
|
self.layout.addWidget(self.tableau)
|
|
81
114
|
|
|
82
|
-
# spaceItem = QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Maximum)
|
|
83
|
-
# self.layout.addItem(spaceItem, 3, 0)
|
|
84
|
-
|
|
85
115
|
# Create the shortcuts row
|
|
86
116
|
self.shortcuts_widget = QtWidgets.QWidget()
|
|
87
117
|
self.shortcuts_layout = QtWidgets.QHBoxLayout()
|
|
88
118
|
self.Video_analysis_window = PButton("Video tracking window", night_mode=self.parent().po.all['night_mode'])
|
|
89
119
|
self.Video_analysis_window.clicked.connect(self.Video_analysis_window_is_clicked)
|
|
90
|
-
self.Run_all_directly = PButton("Run all directly",
|
|
120
|
+
self.Run_all_directly = PButton("Run all directly", tip=VAW["Run_All"]["tips"],
|
|
121
|
+
night_mode=self.parent().po.all['night_mode'])
|
|
91
122
|
self.Run_all_directly.clicked.connect(self.Run_all_directly_is_clicked)
|
|
92
123
|
self.Video_analysis_window.setVisible(False)
|
|
93
124
|
self.Run_all_directly.setVisible(False)
|
|
@@ -101,7 +132,6 @@ class IfSeveralFoldersWindow(WindowType):
|
|
|
101
132
|
self.last_row_layout = QtWidgets.QHBoxLayout()
|
|
102
133
|
self.last_row_widget = QtWidgets.QWidget()
|
|
103
134
|
self.previous = PButton('Previous', night_mode=self.parent().po.all['night_mode'])
|
|
104
|
-
# self.layout.addWidget(self.previous, 4, 0)
|
|
105
135
|
self.previous.clicked.connect(self.previous_is_clicked)
|
|
106
136
|
|
|
107
137
|
# 4) Message
|
|
@@ -109,13 +139,10 @@ class IfSeveralFoldersWindow(WindowType):
|
|
|
109
139
|
self.message.setText('')
|
|
110
140
|
self.message.setStyleSheet("color: rgb(230, 145, 18)")
|
|
111
141
|
self.message.setAlignment(QtCore.Qt.AlignRight)
|
|
112
|
-
# self.layout.addWidget(self.message, 4, 1)
|
|
113
142
|
|
|
114
143
|
# 5) Next button
|
|
115
144
|
self.next = PButton('Next', night_mode=self.parent().po.all['night_mode'])
|
|
116
|
-
# self.layout.addWidget(self.next, 4, 2)
|
|
117
145
|
self.next.clicked.connect(self.next_is_clicked)
|
|
118
|
-
# self.setLayout(self.layout)
|
|
119
146
|
self.last_row_layout.addWidget(self.previous)
|
|
120
147
|
self.last_row_layout.addItem(self.horizontal_space)
|
|
121
148
|
self.last_row_layout.addWidget(self.message)
|
|
@@ -126,23 +153,51 @@ class IfSeveralFoldersWindow(WindowType):
|
|
|
126
153
|
self.setLayout(self.layout)
|
|
127
154
|
|
|
128
155
|
def checked(self):
|
|
156
|
+
"""
|
|
157
|
+
Check or uncheck all entries in the tableau based on checkbox state.
|
|
158
|
+
|
|
159
|
+
If the associated checkbox is checked, select all items in the
|
|
160
|
+
tableau. Otherwise, clear the selection.
|
|
161
|
+
"""
|
|
129
162
|
if self.cb.isChecked():
|
|
130
163
|
self.tableau.selectAll()
|
|
131
164
|
else:
|
|
132
165
|
self.tableau.clearSelection()
|
|
133
166
|
|
|
134
167
|
def item_selection_changed(self):
|
|
168
|
+
"""
|
|
169
|
+
Update the checkbox state based on the number of selected items.
|
|
170
|
+
"""
|
|
135
171
|
if (len(self.tableau.selectedItems()) // 2) == len(self.parent().po.all['folder_list']):
|
|
136
172
|
self.cb.setChecked(True)
|
|
137
173
|
else:
|
|
138
174
|
self.cb.setChecked(False)
|
|
139
175
|
|
|
140
176
|
def previous_is_clicked(self):
|
|
177
|
+
"""
|
|
178
|
+
Handles the logic for when a "Previous" button is clicked in the interface, leading to the FirstWindow.
|
|
179
|
+
|
|
180
|
+
It modifies internal state to force the decision between IfSeveralFoldersWindow and ImageAnalysisWindow to be
|
|
181
|
+
done once again if the user clicks on the "Next" button of the FirstWindow.
|
|
182
|
+
"""
|
|
141
183
|
self.next_clicked_once = False
|
|
142
184
|
self.parent().firstwindow.instantiate = True
|
|
143
185
|
self.parent().change_widget(0)
|
|
144
186
|
|
|
145
187
|
def next_is_clicked(self):
|
|
188
|
+
"""
|
|
189
|
+
Handles the logic for when a "Next" button is clicked in the interface, leading to the ImageAnalysisWindow.
|
|
190
|
+
|
|
191
|
+
If `self.next_clicked_once` is True, instanties widgets and performs image analysis.
|
|
192
|
+
Otherwise, checks for selected folders and samples. Updates internal state and starts
|
|
193
|
+
a thread for loading the first folder if multiple folders are selected.
|
|
194
|
+
|
|
195
|
+
Notes
|
|
196
|
+
-----
|
|
197
|
+
This function updates the internal state based on user selection and starts a thread
|
|
198
|
+
for loading data. The `self.parent().po.update_folder_id` method is called to update
|
|
199
|
+
folder IDs.
|
|
200
|
+
"""
|
|
146
201
|
if self.next_clicked_once:
|
|
147
202
|
self.instantiates_widgets_and_do_image_analysis()
|
|
148
203
|
else:
|
|
@@ -151,12 +206,8 @@ class IfSeveralFoldersWindow(WindowType):
|
|
|
151
206
|
if item_number == 0:
|
|
152
207
|
self.message.setText("Select at least one folder")
|
|
153
208
|
else:
|
|
154
|
-
# self.tableau.selectedItems()
|
|
155
209
|
sample_number_per_folder = []
|
|
156
210
|
folder_list = []
|
|
157
|
-
# sample_number =
|
|
158
|
-
# if isinstance(self.parent().po.all['sample_number_per_folder'], int):
|
|
159
|
-
# sample_number = self.parent().po.all['sample_number_per_folder']
|
|
160
211
|
for i in np.arange(item_number):
|
|
161
212
|
if i % 2 == 0:
|
|
162
213
|
folder_list.append(self.tableau.selectedItems()[i].text())
|
|
@@ -164,31 +215,22 @@ class IfSeveralFoldersWindow(WindowType):
|
|
|
164
215
|
sample_number_per_folder.append(int(self.tableau.selectedItems()[i].text()))
|
|
165
216
|
self.parent().po.all['first_folder_sample_number'] = int(self.tableau.selectedItems()[1].text())
|
|
166
217
|
|
|
167
|
-
#
|
|
168
|
-
# for index in self.tableau.selectionModel().selectedRows():
|
|
169
|
-
# folder_list.append(self.parent().po.all['folder_list'][index.row()])
|
|
170
|
-
# # if not isinstance(self.parent().po.all['sample_number_per_folder'], int):
|
|
171
|
-
# sample_number = self.parent().po.all['sample_number_per_folder'][index.row()]
|
|
172
|
-
# sample_number_per_folder.append(sample_number)
|
|
173
|
-
|
|
174
218
|
self.parent().po.all['folder_list'] = folder_list
|
|
175
219
|
self.parent().po.all['sample_number_per_folder'] = sample_number_per_folder
|
|
176
220
|
self.parent().po.update_folder_id(self.parent().po.all['first_folder_sample_number'],
|
|
177
221
|
self.parent().po.all['folder_list'][0])
|
|
178
|
-
print(os.getcwd())
|
|
179
|
-
# if not isinstance(self.parent().po.all['sample_number_per_folder'], int):
|
|
180
|
-
# self.parent().po.update_folder_id(self.parent().po.all['sample_number_per_folder'][0], self.parent().po.all['folder_list'][0])
|
|
181
|
-
# else:
|
|
182
|
-
# self.parent().po.update_folder_id(self.parent().po.all['sample_number_per_folder'], self.parent().po.all['folder_list'][0])
|
|
183
|
-
|
|
184
|
-
# if self.parent.subwidgets_stack.count() == 5:
|
|
185
|
-
# self.parent.instantiate_widget(ImageAnalysisWindow(self.parent))
|
|
186
|
-
# if not self.parent().imageanalysiswindow.initialized:
|
|
187
|
-
|
|
188
222
|
self.thread["LoadFirstFolderIfSeveral"].start()
|
|
189
223
|
self.thread["LoadFirstFolderIfSeveral"].message_when_thread_finished.connect(self.first_folder_loaded)
|
|
190
224
|
|
|
191
|
-
def first_folder_loaded(self, first_exp_ready_to_run):
|
|
225
|
+
def first_folder_loaded(self, first_exp_ready_to_run: bool):
|
|
226
|
+
"""
|
|
227
|
+
Set the visibility of widgets and messages based on whether data is found.
|
|
228
|
+
|
|
229
|
+
Parameters
|
|
230
|
+
----------
|
|
231
|
+
first_exp_ready_to_run : bool
|
|
232
|
+
Indicates if the experiment data is ready to be run.
|
|
233
|
+
"""
|
|
192
234
|
if first_exp_ready_to_run:
|
|
193
235
|
self.cb_widget.setVisible(False)
|
|
194
236
|
self.tableau.setVisible(False)
|
|
@@ -206,34 +248,41 @@ class IfSeveralFoldersWindow(WindowType):
|
|
|
206
248
|
self.instantiates_widgets_and_do_image_analysis()
|
|
207
249
|
|
|
208
250
|
def instantiates_widgets_and_do_image_analysis(self):
|
|
209
|
-
|
|
251
|
+
"""
|
|
252
|
+
Instantiate widgets and initialize the image analysis window.
|
|
253
|
+
-----
|
|
254
|
+
This function is responsible for:
|
|
255
|
+
- Instantiating widgets with a specific condition.
|
|
256
|
+
- Initializing the true initialization of the image analysis window.
|
|
257
|
+
- Remember to not re-instantiate the image analysis window if the user goes back to the first window.
|
|
258
|
+
- Changing the current widget to ImageAnalysisWindow.
|
|
259
|
+
"""
|
|
210
260
|
self.parent().instantiate_widgets(severalfolder_included=False)
|
|
211
261
|
self.parent().imageanalysiswindow.true_init()
|
|
212
262
|
self.parent().firstwindow.instantiate = False
|
|
213
|
-
print(os.getcwd())
|
|
214
263
|
self.parent().change_widget(2)# ImageAnalysisWindow
|
|
215
|
-
# self.parent().change_widget(3) # VideoAnalysisWindow
|
|
216
264
|
|
|
217
265
|
def Video_analysis_window_is_clicked(self):
|
|
266
|
+
"""
|
|
267
|
+
Save the identity of the current widget (for future navigation) and change to the video analysis window.
|
|
268
|
+
"""
|
|
218
269
|
self.parent().last_tab = "data_specifications"
|
|
219
|
-
# self.parent().po.update_folder_id(self.parent().po.all['sample_number_per_folder'][0],
|
|
220
|
-
# self.parent().po.all['folder_list'][0])
|
|
221
270
|
self.parent().change_widget(3)
|
|
222
271
|
|
|
223
272
|
def Run_all_directly_is_clicked(self):
|
|
273
|
+
"""
|
|
274
|
+
Run the "Run all directly" operation in the parent window.
|
|
275
|
+
|
|
276
|
+
This function triggers the execution of the "Run all directly"
|
|
277
|
+
functionality by calling the corresponding method in the parent
|
|
278
|
+
window and then updates the state accordingly.
|
|
279
|
+
"""
|
|
224
280
|
self.parent().firstwindow.Run_all_directly_is_clicked()
|
|
225
281
|
self.previous_is_clicked()
|
|
226
282
|
|
|
227
283
|
def closeEvent(self, event):
|
|
284
|
+
"""
|
|
285
|
+
Handle the close event for a QWidget.
|
|
286
|
+
"""
|
|
228
287
|
event.accept
|
|
229
288
|
|
|
230
|
-
|
|
231
|
-
# if __name__ == "__main__":
|
|
232
|
-
# from cellects.gui.cellects import CellectsMainWidget
|
|
233
|
-
# import sys
|
|
234
|
-
# app = QtWidgets.QApplication([])
|
|
235
|
-
# parent = CellectsMainWidget()
|
|
236
|
-
# session = IfSeveralFoldersWindow(parent, False)
|
|
237
|
-
# parent.insertWidget(0, session)
|
|
238
|
-
# parent.show()
|
|
239
|
-
# sys.exit(app.exec())
|