boris-behav-obs 8.9.16__py3-none-any.whl → 9.7.6__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.
Potentially problematic release.
This version of boris-behav-obs might be problematic. Click here for more details.
- boris/__init__.py +1 -1
- boris/__main__.py +1 -1
- boris/about.py +36 -39
- boris/add_modifier.py +122 -109
- boris/add_modifier_ui.py +239 -135
- boris/advanced_event_filtering.py +81 -45
- boris/analysis_plugins/__init__.py +0 -0
- boris/analysis_plugins/_latency.py +59 -0
- boris/analysis_plugins/irr_cohen_kappa.py +109 -0
- boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +112 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa.py +157 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +162 -0
- boris/analysis_plugins/list_of_dataframe_columns.py +22 -0
- boris/analysis_plugins/number_of_occurences.py +22 -0
- boris/analysis_plugins/number_of_occurences_by_independent_variable.py +54 -0
- boris/analysis_plugins/time_budget.py +61 -0
- boris/behav_coding_map_creator.py +228 -229
- boris/behavior_binary_table.py +33 -50
- boris/behaviors_coding_map.py +17 -18
- boris/boris_cli.py +6 -25
- boris/cmd_arguments.py +12 -1
- boris/coding_pad.py +42 -49
- boris/config.py +161 -77
- boris/config_file.py +63 -83
- boris/connections.py +112 -57
- boris/converters.py +13 -37
- boris/converters_ui.py +187 -110
- boris/cooccurence.py +250 -0
- boris/core.py +2511 -1824
- boris/core_qrc.py +15895 -10185
- boris/core_ui.py +946 -792
- boris/db_functions.py +21 -41
- boris/dev.py +134 -0
- boris/dialog.py +505 -244
- boris/duration_widget.py +15 -20
- boris/edit_event.py +84 -28
- boris/edit_event_ui.py +214 -78
- boris/event_operations.py +517 -415
- boris/events_cursor.py +25 -17
- boris/events_snapshots.py +36 -82
- boris/exclusion_matrix.py +4 -9
- boris/export_events.py +213 -583
- boris/export_observation.py +98 -611
- boris/external_processes.py +156 -97
- boris/geometric_measurement.py +652 -287
- boris/gui_utilities.py +91 -14
- boris/image_overlay.py +9 -9
- boris/import_observations.py +190 -98
- boris/ipc_mpv.py +325 -0
- boris/irr.py +26 -63
- boris/latency.py +34 -25
- boris/measurement_widget.py +14 -18
- boris/media_file.py +52 -84
- boris/menu_options.py +17 -6
- boris/modifier_coding_map_creator.py +1013 -0
- boris/modifiers_coding_map.py +7 -9
- boris/mpv.py +1 -0
- boris/mpv2.py +732 -705
- boris/observation.py +655 -310
- boris/observation_operations.py +1036 -404
- boris/observation_ui.py +584 -356
- boris/observations_list.py +71 -53
- boris/otx_parser.py +74 -80
- boris/param_panel.py +31 -16
- boris/param_panel_ui.py +254 -138
- boris/player_dock_widget.py +90 -60
- boris/plot_data_module.py +43 -46
- boris/plot_events.py +127 -90
- boris/plot_events_rt.py +17 -31
- boris/plot_spectrogram_rt.py +95 -30
- boris/plot_waveform_rt.py +32 -21
- boris/plugins.py +431 -0
- boris/portion/__init__.py +18 -8
- boris/portion/const.py +35 -18
- boris/portion/dict.py +5 -5
- boris/portion/func.py +2 -2
- boris/portion/interval.py +21 -41
- boris/portion/io.py +41 -32
- boris/preferences.py +306 -83
- boris/preferences_ui.py +685 -228
- boris/project.py +448 -293
- boris/project_functions.py +689 -254
- boris/project_import_export.py +213 -222
- boris/project_ui.py +674 -438
- boris/qrc_boris.py +6 -3
- boris/qrc_boris5.py +6 -3
- boris/select_modifiers.py +74 -48
- boris/select_observations.py +20 -199
- boris/select_subj_behav.py +67 -39
- boris/state_events.py +53 -37
- boris/subjects_pad.py +6 -9
- boris/synthetic_time_budget.py +45 -28
- boris/time_budget_functions.py +171 -171
- boris/time_budget_widget.py +84 -114
- boris/transitions.py +41 -47
- boris/utilities.py +766 -266
- boris/version.py +3 -3
- boris/video_equalizer.py +16 -14
- boris/video_equalizer_ui.py +199 -130
- boris/video_operations.py +125 -28
- boris/view_df.py +104 -0
- boris/view_df_ui.py +75 -0
- boris/write_event.py +538 -0
- boris_behav_obs-9.7.6.dist-info/METADATA +139 -0
- boris_behav_obs-9.7.6.dist-info/RECORD +109 -0
- {boris_behav_obs-8.9.16.dist-info → boris_behav_obs-9.7.6.dist-info}/WHEEL +1 -1
- boris_behav_obs-9.7.6.dist-info/entry_points.txt +2 -0
- boris/README.TXT +0 -22
- boris/add_modifier.ui +0 -323
- boris/boris_ui.py +0 -886
- boris/converters.ui +0 -289
- boris/core.qrc +0 -35
- boris/core.ui +0 -1543
- boris/edit_event.ui +0 -175
- boris/icons/logo_eye.ico +0 -0
- boris/map_creator.py +0 -850
- boris/observation.ui +0 -773
- boris/param_panel.ui +0 -379
- boris/preferences.ui +0 -537
- boris/project.ui +0 -1069
- boris/project_server.py +0 -236
- boris/vlc.py +0 -10343
- boris/vlc_local.py +0 -90
- boris_behav_obs-8.9.16.dist-info/LICENSE.TXT +0 -674
- boris_behav_obs-8.9.16.dist-info/METADATA +0 -129
- boris_behav_obs-8.9.16.dist-info/RECORD +0 -108
- boris_behav_obs-8.9.16.dist-info/entry_points.txt +0 -2
- {boris → boris_behav_obs-9.7.6.dist-info/licenses}/LICENSE.TXT +0 -0
- {boris_behav_obs-8.9.16.dist-info → boris_behav_obs-9.7.6.dist-info}/top_level.txt +0 -0
boris/video_operations.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2025 Olivier Friard
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
This program is free software; you can redistribute it and/or modify
|
|
@@ -26,12 +26,23 @@ import pathlib as pl
|
|
|
26
26
|
import shutil
|
|
27
27
|
from math import log2
|
|
28
28
|
|
|
29
|
-
from
|
|
29
|
+
from PySide6.QtWidgets import QFileDialog
|
|
30
30
|
|
|
31
31
|
from . import config as cfg
|
|
32
32
|
from . import dialog
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
def deinterlace(self):
|
|
36
|
+
"""
|
|
37
|
+
change the deinterlace status of player
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
logging.info("change deinterlace status of player")
|
|
41
|
+
|
|
42
|
+
for dw in self.dw_player:
|
|
43
|
+
dw.player.deinterlace = self.action_deinterlace.isChecked()
|
|
44
|
+
|
|
45
|
+
|
|
35
46
|
def snapshot(self):
|
|
36
47
|
"""
|
|
37
48
|
MEDIA obs: take snapshot of current video at current position
|
|
@@ -41,13 +52,11 @@ def snapshot(self):
|
|
|
41
52
|
"""
|
|
42
53
|
|
|
43
54
|
if self.playerType == cfg.MEDIA:
|
|
44
|
-
|
|
45
55
|
for i, player in enumerate(self.dw_player):
|
|
46
56
|
if (
|
|
47
57
|
str(i + 1) in self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE]
|
|
48
58
|
and self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE][str(i + 1)]
|
|
49
59
|
):
|
|
50
|
-
|
|
51
60
|
p = pl.Path(self.dw_player[0].player.playlist[self.dw_player[0].player.playlist_pos]["filename"])
|
|
52
61
|
|
|
53
62
|
snapshot_file_path = str(p.parent / f"{p.stem}_{player.player.time_pos:0.3f}.png")
|
|
@@ -58,7 +67,6 @@ def snapshot(self):
|
|
|
58
67
|
logging.debug(f"video snapshot saved in {snapshot_file_path}")
|
|
59
68
|
|
|
60
69
|
if self.playerType == cfg.IMAGES:
|
|
61
|
-
|
|
62
70
|
output_file_name, _ = QFileDialog().getSaveFileName(
|
|
63
71
|
self, "Save copy of the current image", pl.Path(self.images_list[self.image_idx]).name
|
|
64
72
|
)
|
|
@@ -71,18 +79,15 @@ def snapshot(self):
|
|
|
71
79
|
|
|
72
80
|
def zoom_level(self):
|
|
73
81
|
"""
|
|
74
|
-
display dialog for zoom level
|
|
82
|
+
display dialog box for setting the zoom level
|
|
75
83
|
"""
|
|
84
|
+
logging.info("change zoom level of player")
|
|
85
|
+
|
|
76
86
|
players_list: list = []
|
|
77
87
|
for idx, dw in enumerate(self.dw_player):
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
players_list.append(("il", f"Player #{idx + 1}", zoom_levels))
|
|
82
|
-
|
|
83
|
-
zl = dialog.Input_dialog(
|
|
84
|
-
label_caption="Select the zoom level", elements_list=players_list, title="Video zoom level"
|
|
85
|
-
)
|
|
88
|
+
players_list.append(("dsb", f"Player #{idx + 1}", 0.1, 12, 0.1, 2**dw.player.video_zoom, 1))
|
|
89
|
+
|
|
90
|
+
zl = dialog.Input_dialog(label_caption="Select the zoom level", elements_list=players_list, title="Video zoom level")
|
|
86
91
|
if not zl.exec_():
|
|
87
92
|
return
|
|
88
93
|
|
|
@@ -90,20 +95,94 @@ def zoom_level(self):
|
|
|
90
95
|
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ZOOM_LEVEL] = {}
|
|
91
96
|
|
|
92
97
|
for idx, dw in enumerate(self.dw_player):
|
|
93
|
-
if
|
|
94
|
-
str(idx + 1), dw.player.video_zoom
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"""
|
|
99
|
-
dw.player.video_pan_x = 0.25
|
|
100
|
-
dw.player.video_pan_x = 0.25
|
|
101
|
-
"""
|
|
98
|
+
if (
|
|
99
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ZOOM_LEVEL].get(str(idx + 1), dw.player.video_zoom)
|
|
100
|
+
!= zl.elements[f"Player #{idx + 1}"].value()
|
|
101
|
+
):
|
|
102
|
+
dw.player.video_zoom = log2(float(zl.elements[f"Player #{idx + 1}"].value()))
|
|
102
103
|
|
|
103
104
|
logging.debug(f"video zoom changed in {dw.player.video_zoom} for player {idx + 1}")
|
|
104
105
|
|
|
105
106
|
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ZOOM_LEVEL][str(idx + 1)] = float(
|
|
106
|
-
zl.elements[f"Player #{idx + 1}"].
|
|
107
|
+
zl.elements[f"Player #{idx + 1}"].value()
|
|
108
|
+
)
|
|
109
|
+
display_zoom_level(self)
|
|
110
|
+
self.project_changed()
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def change_player_offset(self):
|
|
114
|
+
"""
|
|
115
|
+
display dialog box for setting the player time offset
|
|
116
|
+
"""
|
|
117
|
+
logging.info("change the player time offset")
|
|
118
|
+
|
|
119
|
+
if cfg.OFFSET not in self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO]:
|
|
120
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET] = {}
|
|
121
|
+
|
|
122
|
+
players_list: list = []
|
|
123
|
+
|
|
124
|
+
for idx, dw in enumerate(self.dw_player):
|
|
125
|
+
players_list.append(
|
|
126
|
+
(
|
|
127
|
+
"dsb",
|
|
128
|
+
f"Player #{idx + 1}",
|
|
129
|
+
-100000,
|
|
130
|
+
100000,
|
|
131
|
+
0.001,
|
|
132
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(idx + 1)],
|
|
133
|
+
3,
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
zl = dialog.Input_dialog(label_caption="Select the time offset", elements_list=players_list, title="Time offset")
|
|
138
|
+
if not zl.exec_():
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
for idx, dw in enumerate(self.dw_player):
|
|
142
|
+
if (
|
|
143
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET].get(str(idx + 1), 0)
|
|
144
|
+
!= zl.elements[f"Player #{idx + 1}"].value()
|
|
145
|
+
):
|
|
146
|
+
logging.debug(f"time offset of player changed in {zl.elements[f'Player #{idx + 1}'].value()} for player {idx + 1}")
|
|
147
|
+
|
|
148
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(idx + 1)] = float(
|
|
149
|
+
zl.elements[f"Player #{idx + 1}"].value()
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
if self.dw_player[0].player.time_pos is not None:
|
|
153
|
+
cumulative_time_pos = self.getLaps() # for player 1
|
|
154
|
+
self.sync_time(idx, cumulative_time_pos)
|
|
155
|
+
|
|
156
|
+
self.project_changed()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def rotate_displayed_video(self):
|
|
160
|
+
"""
|
|
161
|
+
rotate the displayed video
|
|
162
|
+
"""
|
|
163
|
+
players_list: list = []
|
|
164
|
+
for idx, dw in enumerate(self.dw_player):
|
|
165
|
+
rotation_angles: list = []
|
|
166
|
+
for choice in (0, 90, 180, 270):
|
|
167
|
+
rotation_angles.append((str(choice), "selected" if choice == dw.player.video_rotate else ""))
|
|
168
|
+
players_list.append(("il", f"Player #{idx + 1}", rotation_angles))
|
|
169
|
+
|
|
170
|
+
w = dialog.Input_dialog(label_caption="Select the rotation angle", elements_list=players_list, title="Video rotation angle")
|
|
171
|
+
if not w.exec_():
|
|
172
|
+
return
|
|
173
|
+
if cfg.ROTATION_ANGLE not in self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO]:
|
|
174
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ROTATION_ANGLE] = {}
|
|
175
|
+
|
|
176
|
+
for idx, dw in enumerate(self.dw_player):
|
|
177
|
+
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ROTATION_ANGLE].get(
|
|
178
|
+
str(idx + 1), dw.player.video_rotate
|
|
179
|
+
) != float(w.elements[f"Player #{idx + 1}"].currentText()):
|
|
180
|
+
dw.player.video_rotate = int(w.elements[f"Player #{idx + 1}"].currentText())
|
|
181
|
+
|
|
182
|
+
logging.debug(f"video rotation changed to {dw.player.video_rotate} for player {idx + 1}")
|
|
183
|
+
|
|
184
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ROTATION_ANGLE][str(idx + 1)] = int(
|
|
185
|
+
w.elements[f"Player #{idx + 1}"].currentText()
|
|
107
186
|
)
|
|
108
187
|
self.project_changed()
|
|
109
188
|
|
|
@@ -140,17 +219,34 @@ def display_subtitles(self):
|
|
|
140
219
|
|
|
141
220
|
logging.debug(f"subtitle visibility for player {idx + 1}: {dw.player.sub_visibility}")
|
|
142
221
|
|
|
143
|
-
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.DISPLAY_MEDIA_SUBTITLES][
|
|
144
|
-
|
|
145
|
-
]
|
|
222
|
+
self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.DISPLAY_MEDIA_SUBTITLES][str(idx + 1)] = st.elements[
|
|
223
|
+
f"Player #{idx + 1}"
|
|
224
|
+
].isChecked()
|
|
146
225
|
self.project_changed()
|
|
147
226
|
|
|
148
227
|
|
|
228
|
+
def display_zoom_level(self) -> None:
|
|
229
|
+
"""
|
|
230
|
+
display the zoom level
|
|
231
|
+
"""
|
|
232
|
+
msg: str = "Zoom level: <b>"
|
|
233
|
+
for player in self.dw_player:
|
|
234
|
+
vz = player.player.video_zoom
|
|
235
|
+
if vz is None:
|
|
236
|
+
self.lb_zoom_level.setText("-")
|
|
237
|
+
return
|
|
238
|
+
msg += f"{2**player.player.video_zoom:.1f} "
|
|
239
|
+
msg += "</b>"
|
|
240
|
+
self.lb_zoom_level.setText(msg)
|
|
241
|
+
|
|
242
|
+
|
|
149
243
|
def display_play_rate(self) -> None:
|
|
150
244
|
"""
|
|
151
245
|
display current play rate in status bar widget
|
|
152
246
|
"""
|
|
153
|
-
|
|
247
|
+
|
|
248
|
+
self.lb_video_info.setText(f"Play rate: <b>x{self.play_rate:.3f}</b>")
|
|
249
|
+
|
|
154
250
|
logging.debug(f"play rate: {self.play_rate:.3f}")
|
|
155
251
|
|
|
156
252
|
|
|
@@ -189,6 +285,7 @@ def video_faster_activated(self):
|
|
|
189
285
|
and self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE][str(i + 1)]
|
|
190
286
|
):
|
|
191
287
|
player.player.speed = self.play_rate
|
|
288
|
+
print("speed")
|
|
192
289
|
|
|
193
290
|
display_play_rate(self)
|
|
194
291
|
|
boris/view_df.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from .view_df_ui import Ui_Form
|
|
2
|
+
from PySide6.QtWidgets import QWidget, QFileDialog
|
|
3
|
+
from PySide6.QtCore import Qt, QAbstractTableModel
|
|
4
|
+
|
|
5
|
+
from . import config as cfg
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from . import dialog
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
import pyreadr
|
|
11
|
+
|
|
12
|
+
flag_pyreadr_loaded = True
|
|
13
|
+
except ModuleNotFoundError:
|
|
14
|
+
flag_pyreadr_loaded = False
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DataFrameModel(QAbstractTableModel):
|
|
18
|
+
def __init__(self, dataframe):
|
|
19
|
+
super().__init__()
|
|
20
|
+
self._dataframe = dataframe
|
|
21
|
+
|
|
22
|
+
def rowCount(self, parent=None):
|
|
23
|
+
return self._dataframe.shape[0]
|
|
24
|
+
|
|
25
|
+
def columnCount(self, parent=None):
|
|
26
|
+
return self._dataframe.shape[1]
|
|
27
|
+
|
|
28
|
+
def data(self, index, role=Qt.DisplayRole):
|
|
29
|
+
if role == Qt.DisplayRole:
|
|
30
|
+
return str(self._dataframe.iat[index.row(), index.column()])
|
|
31
|
+
return None
|
|
32
|
+
|
|
33
|
+
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
|
34
|
+
if role == Qt.DisplayRole:
|
|
35
|
+
if orientation == Qt.Horizontal:
|
|
36
|
+
return self._dataframe.columns[section]
|
|
37
|
+
elif orientation == Qt.Vertical:
|
|
38
|
+
return self._dataframe.index[section]
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class View_df(QWidget, Ui_Form):
|
|
43
|
+
def __init__(self, plugin_name: str, plugin_version: str, df, parent=None):
|
|
44
|
+
super().__init__()
|
|
45
|
+
self.plugin_name = plugin_name
|
|
46
|
+
self.df = df
|
|
47
|
+
|
|
48
|
+
self.setupUi(self)
|
|
49
|
+
self.lb_plugin_info.setText(f"{plugin_name} v. {plugin_version}")
|
|
50
|
+
self.setWindowTitle(f"{plugin_name} v. {plugin_version}")
|
|
51
|
+
|
|
52
|
+
self.pb_close.clicked.connect(self.close)
|
|
53
|
+
self.pb_save.clicked.connect(self.save)
|
|
54
|
+
|
|
55
|
+
model = DataFrameModel(self.df)
|
|
56
|
+
self.tv_df.setModel(model)
|
|
57
|
+
|
|
58
|
+
def save(self):
|
|
59
|
+
file_formats = (
|
|
60
|
+
cfg.TSV,
|
|
61
|
+
cfg.CSV,
|
|
62
|
+
cfg.ODS,
|
|
63
|
+
cfg.XLSX,
|
|
64
|
+
# cfg.XLS,
|
|
65
|
+
cfg.HTML,
|
|
66
|
+
# cfg.TBS,
|
|
67
|
+
cfg.PANDAS_DF,
|
|
68
|
+
cfg.RDS,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
file_dialog_options = QFileDialog.Options()
|
|
72
|
+
file_dialog_options |= QFileDialog.DontConfirmOverwrite
|
|
73
|
+
|
|
74
|
+
file_name, filter_ = QFileDialog().getSaveFileName(
|
|
75
|
+
None, f"Save {self.plugin_name}", "", ";;".join(file_formats), options=file_dialog_options
|
|
76
|
+
)
|
|
77
|
+
if not file_name:
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
outputFormat = cfg.FILE_NAME_SUFFIX[filter_]
|
|
81
|
+
if Path(file_name).suffix != "." + outputFormat:
|
|
82
|
+
file_name = f"{file_name}.{outputFormat}"
|
|
83
|
+
if Path(file_name).exists():
|
|
84
|
+
if (
|
|
85
|
+
dialog.MessageDialog(cfg.programName, f"The file {file_name} already exists.", [cfg.CANCEL, cfg.OVERWRITE])
|
|
86
|
+
== cfg.CANCEL
|
|
87
|
+
):
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
if filter_ == cfg.TSV:
|
|
91
|
+
self.df.to_csv(file_name, sep="\t", index=False)
|
|
92
|
+
if filter_ == cfg.CSV:
|
|
93
|
+
self.df.to_csv(file_name, sep=";", index=False)
|
|
94
|
+
if filter_ == cfg.XLSX:
|
|
95
|
+
self.df.to_excel(file_name, index=False)
|
|
96
|
+
if filter_ == cfg.ODS:
|
|
97
|
+
self.df.to_excel(file_name, index=False, engine="odf")
|
|
98
|
+
if filter_ == cfg.HTML:
|
|
99
|
+
self.df.to_html(file_name, index=False)
|
|
100
|
+
if filter_ == cfg.PANDAS_DF:
|
|
101
|
+
self.df.to_pickle(file_name)
|
|
102
|
+
|
|
103
|
+
if filter_ == cfg.RDS and flag_pyreadr_loaded:
|
|
104
|
+
pyreadr.write_rds(file_name, self.df)
|
boris/view_df_ui.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
################################################################################
|
|
4
|
+
## Form generated from reading UI file 'view_df.ui'
|
|
5
|
+
##
|
|
6
|
+
## Created by: Qt User Interface Compiler version 6.8.0
|
|
7
|
+
##
|
|
8
|
+
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
9
|
+
################################################################################
|
|
10
|
+
|
|
11
|
+
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
|
12
|
+
QMetaObject, QObject, QPoint, QRect,
|
|
13
|
+
QSize, QTime, QUrl, Qt)
|
|
14
|
+
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|
15
|
+
QFont, QFontDatabase, QGradient, QIcon,
|
|
16
|
+
QImage, QKeySequence, QLinearGradient, QPainter,
|
|
17
|
+
QPalette, QPixmap, QRadialGradient, QTransform)
|
|
18
|
+
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QHeaderView, QLabel,
|
|
19
|
+
QPushButton, QSizePolicy, QSpacerItem, QTableView,
|
|
20
|
+
QVBoxLayout, QWidget)
|
|
21
|
+
|
|
22
|
+
class Ui_Form(object):
|
|
23
|
+
def setupUi(self, Form):
|
|
24
|
+
if not Form.objectName():
|
|
25
|
+
Form.setObjectName(u"Form")
|
|
26
|
+
Form.resize(400, 300)
|
|
27
|
+
self.verticalLayout_2 = QVBoxLayout(Form)
|
|
28
|
+
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
|
29
|
+
self.lb_plugin_info = QLabel(Form)
|
|
30
|
+
self.lb_plugin_info.setObjectName(u"lb_plugin_info")
|
|
31
|
+
|
|
32
|
+
self.verticalLayout_2.addWidget(self.lb_plugin_info)
|
|
33
|
+
|
|
34
|
+
self.verticalLayout = QVBoxLayout()
|
|
35
|
+
self.verticalLayout.setObjectName(u"verticalLayout")
|
|
36
|
+
self.tv_df = QTableView(Form)
|
|
37
|
+
self.tv_df.setObjectName(u"tv_df")
|
|
38
|
+
|
|
39
|
+
self.verticalLayout.addWidget(self.tv_df)
|
|
40
|
+
|
|
41
|
+
self.horizontalLayout = QHBoxLayout()
|
|
42
|
+
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
|
43
|
+
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
44
|
+
|
|
45
|
+
self.horizontalLayout.addItem(self.horizontalSpacer)
|
|
46
|
+
|
|
47
|
+
self.pb_save = QPushButton(Form)
|
|
48
|
+
self.pb_save.setObjectName(u"pb_save")
|
|
49
|
+
|
|
50
|
+
self.horizontalLayout.addWidget(self.pb_save)
|
|
51
|
+
|
|
52
|
+
self.pb_close = QPushButton(Form)
|
|
53
|
+
self.pb_close.setObjectName(u"pb_close")
|
|
54
|
+
|
|
55
|
+
self.horizontalLayout.addWidget(self.pb_close)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
self.verticalLayout.addLayout(self.horizontalLayout)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
self.verticalLayout_2.addLayout(self.verticalLayout)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
self.retranslateUi(Form)
|
|
65
|
+
|
|
66
|
+
QMetaObject.connectSlotsByName(Form)
|
|
67
|
+
# setupUi
|
|
68
|
+
|
|
69
|
+
def retranslateUi(self, Form):
|
|
70
|
+
Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
|
|
71
|
+
self.lb_plugin_info.setText(QCoreApplication.translate("Form", u"TextLabel", None))
|
|
72
|
+
self.pb_save.setText(QCoreApplication.translate("Form", u"Save results", None))
|
|
73
|
+
self.pb_close.setText(QCoreApplication.translate("Form", u"Close", None))
|
|
74
|
+
# retranslateUi
|
|
75
|
+
|