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.

Files changed (129) hide show
  1. boris/__init__.py +1 -1
  2. boris/__main__.py +1 -1
  3. boris/about.py +36 -39
  4. boris/add_modifier.py +122 -109
  5. boris/add_modifier_ui.py +239 -135
  6. boris/advanced_event_filtering.py +81 -45
  7. boris/analysis_plugins/__init__.py +0 -0
  8. boris/analysis_plugins/_latency.py +59 -0
  9. boris/analysis_plugins/irr_cohen_kappa.py +109 -0
  10. boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +112 -0
  11. boris/analysis_plugins/irr_weighted_cohen_kappa.py +157 -0
  12. boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +162 -0
  13. boris/analysis_plugins/list_of_dataframe_columns.py +22 -0
  14. boris/analysis_plugins/number_of_occurences.py +22 -0
  15. boris/analysis_plugins/number_of_occurences_by_independent_variable.py +54 -0
  16. boris/analysis_plugins/time_budget.py +61 -0
  17. boris/behav_coding_map_creator.py +228 -229
  18. boris/behavior_binary_table.py +33 -50
  19. boris/behaviors_coding_map.py +17 -18
  20. boris/boris_cli.py +6 -25
  21. boris/cmd_arguments.py +12 -1
  22. boris/coding_pad.py +42 -49
  23. boris/config.py +161 -77
  24. boris/config_file.py +63 -83
  25. boris/connections.py +112 -57
  26. boris/converters.py +13 -37
  27. boris/converters_ui.py +187 -110
  28. boris/cooccurence.py +250 -0
  29. boris/core.py +2511 -1824
  30. boris/core_qrc.py +15895 -10185
  31. boris/core_ui.py +946 -792
  32. boris/db_functions.py +21 -41
  33. boris/dev.py +134 -0
  34. boris/dialog.py +505 -244
  35. boris/duration_widget.py +15 -20
  36. boris/edit_event.py +84 -28
  37. boris/edit_event_ui.py +214 -78
  38. boris/event_operations.py +517 -415
  39. boris/events_cursor.py +25 -17
  40. boris/events_snapshots.py +36 -82
  41. boris/exclusion_matrix.py +4 -9
  42. boris/export_events.py +213 -583
  43. boris/export_observation.py +98 -611
  44. boris/external_processes.py +156 -97
  45. boris/geometric_measurement.py +652 -287
  46. boris/gui_utilities.py +91 -14
  47. boris/image_overlay.py +9 -9
  48. boris/import_observations.py +190 -98
  49. boris/ipc_mpv.py +325 -0
  50. boris/irr.py +26 -63
  51. boris/latency.py +34 -25
  52. boris/measurement_widget.py +14 -18
  53. boris/media_file.py +52 -84
  54. boris/menu_options.py +17 -6
  55. boris/modifier_coding_map_creator.py +1013 -0
  56. boris/modifiers_coding_map.py +7 -9
  57. boris/mpv.py +1 -0
  58. boris/mpv2.py +732 -705
  59. boris/observation.py +655 -310
  60. boris/observation_operations.py +1036 -404
  61. boris/observation_ui.py +584 -356
  62. boris/observations_list.py +71 -53
  63. boris/otx_parser.py +74 -80
  64. boris/param_panel.py +31 -16
  65. boris/param_panel_ui.py +254 -138
  66. boris/player_dock_widget.py +90 -60
  67. boris/plot_data_module.py +43 -46
  68. boris/plot_events.py +127 -90
  69. boris/plot_events_rt.py +17 -31
  70. boris/plot_spectrogram_rt.py +95 -30
  71. boris/plot_waveform_rt.py +32 -21
  72. boris/plugins.py +431 -0
  73. boris/portion/__init__.py +18 -8
  74. boris/portion/const.py +35 -18
  75. boris/portion/dict.py +5 -5
  76. boris/portion/func.py +2 -2
  77. boris/portion/interval.py +21 -41
  78. boris/portion/io.py +41 -32
  79. boris/preferences.py +306 -83
  80. boris/preferences_ui.py +685 -228
  81. boris/project.py +448 -293
  82. boris/project_functions.py +689 -254
  83. boris/project_import_export.py +213 -222
  84. boris/project_ui.py +674 -438
  85. boris/qrc_boris.py +6 -3
  86. boris/qrc_boris5.py +6 -3
  87. boris/select_modifiers.py +74 -48
  88. boris/select_observations.py +20 -199
  89. boris/select_subj_behav.py +67 -39
  90. boris/state_events.py +53 -37
  91. boris/subjects_pad.py +6 -9
  92. boris/synthetic_time_budget.py +45 -28
  93. boris/time_budget_functions.py +171 -171
  94. boris/time_budget_widget.py +84 -114
  95. boris/transitions.py +41 -47
  96. boris/utilities.py +766 -266
  97. boris/version.py +3 -3
  98. boris/video_equalizer.py +16 -14
  99. boris/video_equalizer_ui.py +199 -130
  100. boris/video_operations.py +125 -28
  101. boris/view_df.py +104 -0
  102. boris/view_df_ui.py +75 -0
  103. boris/write_event.py +538 -0
  104. boris_behav_obs-9.7.6.dist-info/METADATA +139 -0
  105. boris_behav_obs-9.7.6.dist-info/RECORD +109 -0
  106. {boris_behav_obs-8.9.16.dist-info → boris_behav_obs-9.7.6.dist-info}/WHEEL +1 -1
  107. boris_behav_obs-9.7.6.dist-info/entry_points.txt +2 -0
  108. boris/README.TXT +0 -22
  109. boris/add_modifier.ui +0 -323
  110. boris/boris_ui.py +0 -886
  111. boris/converters.ui +0 -289
  112. boris/core.qrc +0 -35
  113. boris/core.ui +0 -1543
  114. boris/edit_event.ui +0 -175
  115. boris/icons/logo_eye.ico +0 -0
  116. boris/map_creator.py +0 -850
  117. boris/observation.ui +0 -773
  118. boris/param_panel.ui +0 -379
  119. boris/preferences.ui +0 -537
  120. boris/project.ui +0 -1069
  121. boris/project_server.py +0 -236
  122. boris/vlc.py +0 -10343
  123. boris/vlc_local.py +0 -90
  124. boris_behav_obs-8.9.16.dist-info/LICENSE.TXT +0 -674
  125. boris_behav_obs-8.9.16.dist-info/METADATA +0 -129
  126. boris_behav_obs-8.9.16.dist-info/RECORD +0 -108
  127. boris_behav_obs-8.9.16.dist-info/entry_points.txt +0 -2
  128. {boris → boris_behav_obs-9.7.6.dist-info/licenses}/LICENSE.TXT +0 -0
  129. {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-2023 Olivier Friard
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 PyQt5.QtWidgets import QFileDialog
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
- zoom_levels: list = []
79
- for choice in (2, 1, 0.5, 0.25):
80
- zoom_levels.append((str(choice), "selected" if log2(choice) == dw.player.video_zoom else ""))
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 self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.ZOOM_LEVEL].get(
94
- str(idx + 1), dw.player.video_zoom
95
- ) != float(zl.elements[f"Player #{idx + 1}"].currentText()):
96
- dw.player.video_zoom = log2(float(zl.elements[f"Player #{idx + 1}"].currentText()))
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}"].currentText()
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
- str(idx + 1)
145
- ] = st.elements[f"Player #{idx + 1}"].isChecked()
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
- self.lbSpeed.setText(f"Play rate: <b>x{self.play_rate:.3f}</b>")
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
+