cfclient 2024.7.1__py3-none-any.whl → 2025.12.1__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.
Files changed (55) hide show
  1. cfclient/__init__.py +9 -7
  2. cfclient/configs/config.json +1 -1
  3. cfclient/configs/log/PID_tuning/Attitude.json +46 -0
  4. cfclient/configs/log/PID_tuning/Attitude_rate.json +46 -0
  5. cfclient/configs/log/PID_tuning/Position.json +46 -0
  6. cfclient/configs/log/PID_tuning/Velocity.json +46 -0
  7. cfclient/configs/log/PID_tuning_components/Pitch.json +22 -0
  8. cfclient/configs/log/PID_tuning_components/Pitch_rate.json +22 -0
  9. cfclient/configs/log/PID_tuning_components/Position_x.json +22 -0
  10. cfclient/configs/log/PID_tuning_components/Position_y.json +22 -0
  11. cfclient/configs/log/PID_tuning_components/Position_z.json +22 -0
  12. cfclient/configs/log/PID_tuning_components/Roll.json +22 -0
  13. cfclient/configs/log/PID_tuning_components/Roll_rate.json +22 -0
  14. cfclient/configs/log/PID_tuning_components/Velocity_x.json +22 -0
  15. cfclient/configs/log/PID_tuning_components/Velocity_y.json +22 -0
  16. cfclient/configs/log/PID_tuning_components/Velocity_z.json +22 -0
  17. cfclient/configs/log/PID_tuning_components/Yaw.json +22 -0
  18. cfclient/configs/log/PID_tuning_components/Yaw_rate.json +22 -0
  19. cfclient/resources/log_param_doc.json +1 -1
  20. cfclient/ui/dialogs/about.py +5 -1
  21. cfclient/ui/dialogs/basestation_mode_dialog.py +12 -1
  22. cfclient/ui/dialogs/bootloader.py +76 -6
  23. cfclient/ui/dialogs/bootloader.ui +110 -24
  24. cfclient/ui/dialogs/cf2config.ui +1 -1
  25. cfclient/ui/dialogs/lighthouse_bs_geometry_dialog.py +0 -12
  26. cfclient/ui/dialogs/lighthouse_bs_geometry_dialog.ui +0 -7
  27. cfclient/ui/icons/bl.webp +0 -0
  28. cfclient/ui/icons/bolt.webp +0 -0
  29. cfclient/ui/icons/cf21.webp +0 -0
  30. cfclient/ui/icons/flapper.webp +0 -0
  31. cfclient/ui/icons/tag.webp +0 -0
  32. cfclient/ui/main.py +3 -3
  33. cfclient/ui/main.ui +1 -1
  34. cfclient/ui/tabs/ColorLEDTab.py +752 -0
  35. cfclient/ui/tabs/FlightTab.py +11 -108
  36. cfclient/ui/tabs/{LEDTab.py → LEDRingTab.py} +126 -12
  37. cfclient/ui/tabs/LogTab.py +2 -2
  38. cfclient/ui/tabs/ParamTab.py +90 -4
  39. cfclient/ui/tabs/__init__.py +4 -2
  40. cfclient/ui/tabs/colorLEDTab.ui +624 -0
  41. cfclient/ui/tabs/consoleTab.ui +1 -1
  42. cfclient/ui/tabs/flightTab.ui +28 -71
  43. cfclient/ui/tabs/{ledTab.ui → ledRingTab.ui} +63 -46
  44. cfclient/utils/input/__init__.py +3 -3
  45. cfclient/utils/periodictimer.py +1 -1
  46. cfclient/version.py +34 -0
  47. cfclient-2025.12.1.dist-info/METADATA +70 -0
  48. {cfclient-2024.7.1.dist-info → cfclient-2025.12.1.dist-info}/RECORD +54 -28
  49. {cfclient-2024.7.1.dist-info → cfclient-2025.12.1.dist-info}/WHEEL +1 -1
  50. {cfclient-2024.7.1.dist-info → cfclient-2025.12.1.dist-info}/top_level.txt +1 -0
  51. cfconfig/Makefile +51 -0
  52. cfconfig/configblock.py +111 -0
  53. cfclient-2024.7.1.dist-info/METADATA +0 -53
  54. {cfclient-2024.7.1.dist-info → cfclient-2025.12.1.dist-info}/entry_points.txt +0 -0
  55. {cfclient-2024.7.1.dist-info → cfclient-2025.12.1.dist-info/licenses}/LICENSE.txt +0 -0
@@ -217,7 +217,9 @@ class AboutDialog(QtWidgets.QWidget, about_widget_class):
217
217
 
218
218
  def _request_deck_data_update(self):
219
219
  self._decks_text = ""
220
+ # Query both 1-Wire and DeckCtrl memories for deck information
220
221
  mems = self._helper.cf.mem.get_mems(MemoryElement.TYPE_1W)
222
+ mems += self._helper.cf.mem.get_mems(MemoryElement.TYPE_DECKCTRL)
221
223
  for mem in mems:
222
224
  mem.update(self._cb_deck_data_updated_signal.emit)
223
225
 
@@ -230,6 +232,8 @@ class AboutDialog(QtWidgets.QWidget, about_widget_class):
230
232
  if "Board revision" in deck_data.elements:
231
233
  rev = deck_data.elements["Board revision"]
232
234
 
233
- self._decks_text += DECK_FORMAT.format(name, rev, deck_data.addr)
235
+ # OWElement has addr attribute, DeckCtrlElement does not
236
+ addr = getattr(deck_data, 'addr', 'N/A')
237
+ self._decks_text += DECK_FORMAT.format(name, rev, addr)
234
238
 
235
239
  self._update_debug_info_view()
@@ -114,7 +114,18 @@ class LighthouseBsModeDialog(QtWidgets.QWidget, basestation_mode_widget_class):
114
114
  def _set_basestation_pressed(self):
115
115
  self._set_basestation_button.setEnabled(False)
116
116
  dev = self._device
117
- ser = serial.Serial(dev, timeout=0.4)
117
+ try:
118
+ ser = serial.Serial(dev, timeout=0.4)
119
+ except serial.SerialException:
120
+ self._basestation_mode_status.setText(
121
+ 'Permission denied: cannot access serial port.\n'
122
+ 'Try running: \"sudo usermod -aG dialout [username]\" '
123
+ 'and then restart your computer.'
124
+ )
125
+
126
+ self._set_basestation_button.setEnabled(True)
127
+ return
128
+
118
129
  sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))
119
130
  sio.write("\r\nmode " + str(self._channel) + "\r\n")
120
131
  sio.flush()
@@ -45,7 +45,8 @@ from urllib.error import URLError
45
45
  import zipfile
46
46
 
47
47
  from PyQt6 import QtWidgets, uic
48
- from PyQt6.QtCore import pyqtSlot, pyqtSignal, QThread
48
+ from PyQt6.QtCore import pyqtSlot, pyqtSignal, QThread, Qt
49
+ from PyQt6.QtGui import QPixmap
49
50
 
50
51
  import cfclient
51
52
  import cflib.crazyflie
@@ -62,6 +63,8 @@ service_dialog_class = uic.loadUiType(cfclient.module_path +
62
63
  RELEASE_URL = 'https://api.github.com/repos/bitcraze/'\
63
64
  'crazyflie-release/releases'
64
65
 
66
+ ICON_PATH = os.path.join(cfclient.module_path, 'ui', 'icons')
67
+
65
68
 
66
69
  class BootloaderDialog(QtWidgets.QWidget, service_dialog_class):
67
70
  """Tab for update the Crazyflie firmware and for reading/writing the config
@@ -97,6 +100,7 @@ class BootloaderDialog(QtWidgets.QWidget, service_dialog_class):
97
100
  self.programButton.clicked.connect(self.programAction)
98
101
  self.coldBootButton.clicked.connect(self.initiateColdboot)
99
102
  self.resetButton.clicked.connect(self.resetCopter)
103
+ self.sourceTab.currentChanged.connect(self._update_program_button_state)
100
104
 
101
105
  self._helper.connectivity_manager.register_ui_elements(
102
106
  ConnectivityManager.UiElementsContainer(
@@ -132,10 +136,33 @@ class BootloaderDialog(QtWidgets.QWidget, service_dialog_class):
132
136
 
133
137
  self._platform_filter_checkboxes = []
134
138
 
139
+ self._set_image(self.image_1, os.path.join(ICON_PATH, "bolt.webp"))
140
+ self._set_image(self.image_2, os.path.join(ICON_PATH, "cf21.webp"))
141
+ self._set_image(self.image_3, os.path.join(ICON_PATH, "bl.webp"))
142
+ self._set_image(self.image_4, os.path.join(ICON_PATH, "flapper.webp"))
143
+ self._set_image(self.image_5, os.path.join(ICON_PATH, "tag.webp"))
144
+
135
145
  def _ui_connection_fail(self, message):
136
146
  self._cold_boot_error_message = message
137
147
  self.setUiState(self.UIState.DISCONNECTED)
138
148
 
149
+ def _set_image(self, image_label, image_path):
150
+ IMAGE_WIDTH = 100
151
+ IMAGE_HEIGHT = 100
152
+
153
+ pixmap = QPixmap(image_path)
154
+
155
+ if pixmap.isNull():
156
+ logger.warning(f"Failed to load image: {image_path}")
157
+ image_label.setText("Missing image")
158
+ else:
159
+ scaled_pixmap = pixmap.scaled(
160
+ IMAGE_WIDTH, IMAGE_HEIGHT,
161
+ Qt.AspectRatioMode.KeepAspectRatio,
162
+ Qt.TransformationMode.SmoothTransformation
163
+ )
164
+ image_label.setPixmap(scaled_pixmap)
165
+
139
166
  def setUiState(self, state):
140
167
  self._state = state
141
168
 
@@ -163,7 +190,10 @@ class BootloaderDialog(QtWidgets.QWidget, service_dialog_class):
163
190
  elif (state == self.UIState.COLD_CONNECTED):
164
191
  self._cold_boot_error_message = None
165
192
  self.resetButton.setEnabled(True)
166
- self.programButton.setEnabled(True)
193
+ if any(button.isChecked() for button in self._platform_filter_checkboxes):
194
+ self.programButton.setEnabled(True)
195
+ else:
196
+ self.programButton.setToolTip("Select a platform before programming.")
167
197
  self.setStatusLabel("Connected to bootloader")
168
198
  self.coldBootButton.setEnabled(False)
169
199
  self.imagePathBrowseButton.setEnabled(True)
@@ -189,7 +219,10 @@ class BootloaderDialog(QtWidgets.QWidget, service_dialog_class):
189
219
  self.setStatusLabel("Connected using USB")
190
220
  self.setSourceSelectionUiEnabled(False)
191
221
  else:
192
- self.programButton.setEnabled(True)
222
+ if any(button.isChecked() for button in self._platform_filter_checkboxes):
223
+ self.programButton.setEnabled(True)
224
+ else:
225
+ self.programButton.setToolTip("Select a platform before programming.")
193
226
  self.setStatusLabel("Connected in firmware mode")
194
227
  self.setSourceSelectionUiEnabled(True)
195
228
  elif (state == self.UIState.FW_SCANNING):
@@ -216,6 +249,7 @@ class BootloaderDialog(QtWidgets.QWidget, service_dialog_class):
216
249
  self.coldBootButton.setEnabled(False)
217
250
  self.setSourceSelectionUiEnabled(True)
218
251
  self._helper.connectivity_manager.set_enable(False)
252
+ self._update_program_button_state()
219
253
 
220
254
  def setSourceSelectionUiEnabled(self, enabled):
221
255
  self.imagePathBrowseButton.setEnabled(enabled)
@@ -265,19 +299,54 @@ class BootloaderDialog(QtWidgets.QWidget, service_dialog_class):
265
299
  platforms.add(platform)
266
300
 
267
301
  for platform in sorted(platforms, reverse=True):
302
+ RADIO_BUTTON_WIDTH = 100
303
+
268
304
  radio_button = QtWidgets.QRadioButton(platform)
269
305
 
270
- # Use cf2 as default platform
271
- if platform == 'cf2':
272
- radio_button.setChecked(True)
306
+ radio_button.setFixedWidth(RADIO_BUTTON_WIDTH)
273
307
 
274
308
  radio_button.toggled.connect(self._update_firmware_dropdown)
309
+ radio_button.toggled.connect(self._update_program_button_state)
275
310
 
276
311
  self._platform_filter_checkboxes.append(radio_button)
277
312
  self.filterLayout.insertWidget(0, radio_button)
278
313
 
314
+ self.firmwareDropdown.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToContents)
279
315
  self._update_firmware_dropdown(True)
280
316
 
317
+ def _has_selected_file(self) -> bool:
318
+ return bool(self.imagePathLine.text())
319
+
320
+ def _update_program_button_state(self):
321
+ is_connected = self._state in (
322
+ self.UIState.COLD_CONNECTED,
323
+ self.UIState.FW_CONNECTED
324
+ )
325
+
326
+ if not is_connected:
327
+ self.programButton.setEnabled(False)
328
+ self.programButton.setToolTip("Connect your device before programming.")
329
+ return
330
+
331
+ current_tab = self.sourceTab.currentWidget()
332
+
333
+ if current_tab == self.tabFromFile:
334
+ has_file = bool(self.imagePathLine.text())
335
+ self.programButton.setEnabled(has_file)
336
+
337
+ self.programButton.setToolTip(
338
+ "" if has_file else "Choose a firmware file to program."
339
+ )
340
+ else:
341
+ any_platform_checked = any(
342
+ button.isChecked() for button in self._platform_filter_checkboxes
343
+ )
344
+
345
+ self.programButton.setEnabled(any_platform_checked)
346
+ self.programButton.setToolTip(
347
+ "" if any_platform_checked else "Select a platform before programming."
348
+ )
349
+
281
350
  def _update_firmware_dropdown(self, active: bool):
282
351
  if active:
283
352
  platform = None
@@ -341,6 +410,7 @@ class BootloaderDialog(QtWidgets.QWidget, service_dialog_class):
341
410
 
342
411
  if filename.endswith('.zip'):
343
412
  self.imagePathLine.setText(filename)
413
+ self._update_program_button_state()
344
414
  else:
345
415
  msgBox = QtWidgets.QMessageBox()
346
416
  msgBox.setText("Wrong file extention. Must be .zip.")
@@ -3,7 +3,7 @@
3
3
  <class>Form</class>
4
4
  <widget class="QWidget" name="Form">
5
5
  <property name="windowModality">
6
- <enum>Qt::ApplicationModal</enum>
6
+ <enum>Qt::WindowModality::ApplicationModal</enum>
7
7
  </property>
8
8
  <property name="enabled">
9
9
  <bool>true</bool>
@@ -94,7 +94,7 @@
94
94
  <item>
95
95
  <spacer name="horizontalSpacer">
96
96
  <property name="orientation">
97
- <enum>Qt::Horizontal</enum>
97
+ <enum>Qt::Orientation::Horizontal</enum>
98
98
  </property>
99
99
  <property name="sizeHint" stdset="0">
100
100
  <size>
@@ -133,7 +133,7 @@
133
133
  <item>
134
134
  <spacer name="horizontalSpacer_5">
135
135
  <property name="orientation">
136
- <enum>Qt::Horizontal</enum>
136
+ <enum>Qt::Orientation::Horizontal</enum>
137
137
  </property>
138
138
  <property name="sizeHint" stdset="0">
139
139
  <size>
@@ -177,36 +177,122 @@
177
177
  <string>From release</string>
178
178
  </attribute>
179
179
  <layout class="QGridLayout" name="gridLayout">
180
- <item row="0" column="0">
180
+ <item row="1" column="0">
181
181
  <widget class="QGroupBox" name="platform_filter_gb">
182
182
  <property name="title">
183
- <string>Platform filter</string>
183
+ <string>Select a platform:</string>
184
184
  </property>
185
185
  <layout class="QHBoxLayout" name="horizontalLayout_7">
186
186
  <item>
187
- <layout class="QHBoxLayout" name="filterLayout">
187
+ <layout class="QVBoxLayout" name="verticalLayout_5">
188
188
  <item>
189
- <spacer name="horizontalSpacer_6">
190
- <property name="orientation">
191
- <enum>Qt::Horizontal</enum>
192
- </property>
193
- <property name="sizeHint" stdset="0">
194
- <size>
195
- <width>40</width>
196
- <height>20</height>
197
- </size>
198
- </property>
199
- </spacer>
189
+ <layout class="QGridLayout" name="gridLayout_6">
190
+ <item row="0" column="2">
191
+ <widget class="QLabel" name="image_3">
192
+ <property name="maximumSize">
193
+ <size>
194
+ <width>100</width>
195
+ <height>100</height>
196
+ </size>
197
+ </property>
198
+ <property name="text">
199
+ <string>Image 3</string>
200
+ </property>
201
+ </widget>
202
+ </item>
203
+ <item row="0" column="1">
204
+ <widget class="QLabel" name="image_2">
205
+ <property name="maximumSize">
206
+ <size>
207
+ <width>100</width>
208
+ <height>100</height>
209
+ </size>
210
+ </property>
211
+ <property name="text">
212
+ <string>Image 2</string>
213
+ </property>
214
+ </widget>
215
+ </item>
216
+ <item row="0" column="5">
217
+ <spacer name="horizontalSpacer_7">
218
+ <property name="orientation">
219
+ <enum>Qt::Orientation::Horizontal</enum>
220
+ </property>
221
+ <property name="sizeHint" stdset="0">
222
+ <size>
223
+ <width>40</width>
224
+ <height>20</height>
225
+ </size>
226
+ </property>
227
+ </spacer>
228
+ </item>
229
+ <item row="0" column="3">
230
+ <widget class="QLabel" name="image_4">
231
+ <property name="maximumSize">
232
+ <size>
233
+ <width>100</width>
234
+ <height>100</height>
235
+ </size>
236
+ </property>
237
+ <property name="text">
238
+ <string>Image 4</string>
239
+ </property>
240
+ </widget>
241
+ </item>
242
+ <item row="0" column="0">
243
+ <widget class="QLabel" name="image_1">
244
+ <property name="maximumSize">
245
+ <size>
246
+ <width>100</width>
247
+ <height>100</height>
248
+ </size>
249
+ </property>
250
+ <property name="text">
251
+ <string>Image 1</string>
252
+ </property>
253
+ </widget>
254
+ </item>
255
+ <item row="0" column="4">
256
+ <widget class="QLabel" name="image_5">
257
+ <property name="maximumSize">
258
+ <size>
259
+ <width>100</width>
260
+ <height>100</height>
261
+ </size>
262
+ </property>
263
+ <property name="text">
264
+ <string>Image 5</string>
265
+ </property>
266
+ </widget>
267
+ </item>
268
+ </layout>
269
+ </item>
270
+ <item>
271
+ <layout class="QHBoxLayout" name="filterLayout">
272
+ <item>
273
+ <spacer name="horizontalSpacer_6">
274
+ <property name="orientation">
275
+ <enum>Qt::Orientation::Horizontal</enum>
276
+ </property>
277
+ <property name="sizeHint" stdset="0">
278
+ <size>
279
+ <width>40</width>
280
+ <height>20</height>
281
+ </size>
282
+ </property>
283
+ </spacer>
284
+ </item>
285
+ </layout>
200
286
  </item>
201
287
  </layout>
202
288
  </item>
203
289
  </layout>
204
290
  </widget>
205
291
  </item>
206
- <item row="4" column="0">
292
+ <item row="5" column="0">
207
293
  <spacer name="verticalSpacer">
208
294
  <property name="orientation">
209
- <enum>Qt::Vertical</enum>
295
+ <enum>Qt::Orientation::Vertical</enum>
210
296
  </property>
211
297
  <property name="sizeHint" stdset="0">
212
298
  <size>
@@ -216,7 +302,7 @@
216
302
  </property>
217
303
  </spacer>
218
304
  </item>
219
- <item row="1" column="0">
305
+ <item row="2" column="0">
220
306
  <layout class="QHBoxLayout" name="horizontalLayout_2">
221
307
  <item>
222
308
  <widget class="QLabel" name="label_2">
@@ -231,7 +317,7 @@
231
317
  <item>
232
318
  <spacer name="horizontalSpacer_4">
233
319
  <property name="orientation">
234
- <enum>Qt::Horizontal</enum>
320
+ <enum>Qt::Orientation::Horizontal</enum>
235
321
  </property>
236
322
  <property name="sizeHint" stdset="0">
237
323
  <size>
@@ -286,7 +372,7 @@
286
372
  <item>
287
373
  <spacer name="horizontalSpacer_3">
288
374
  <property name="orientation">
289
- <enum>Qt::Horizontal</enum>
375
+ <enum>Qt::Orientation::Horizontal</enum>
290
376
  </property>
291
377
  <property name="sizeHint" stdset="0">
292
378
  <size>
@@ -305,7 +391,7 @@
305
391
  <item>
306
392
  <spacer name="verticalSpacer_3">
307
393
  <property name="orientation">
308
- <enum>Qt::Vertical</enum>
394
+ <enum>Qt::Orientation::Vertical</enum>
309
395
  </property>
310
396
  <property name="sizeHint" stdset="0">
311
397
  <size>
@@ -320,7 +406,7 @@
320
406
  <item>
321
407
  <spacer name="horizontalSpacer_2">
322
408
  <property name="orientation">
323
- <enum>Qt::Horizontal</enum>
409
+ <enum>Qt::Orientation::Horizontal</enum>
324
410
  </property>
325
411
  <property name="sizeHint" stdset="0">
326
412
  <size>
@@ -17,7 +17,7 @@
17
17
  </rect>
18
18
  </property>
19
19
  <property name="windowTitle">
20
- <string>Crazyflie 2.X config</string>
20
+ <string>Crazyflie 2.x config</string>
21
21
  </property>
22
22
  <layout class="QGridLayout" name="gridLayout_3">
23
23
  <item row="0" column="0">
@@ -31,7 +31,6 @@ import cfclient
31
31
  from PyQt6 import QtWidgets
32
32
  from PyQt6 import uic
33
33
  from PyQt6.QtCore import QVariant, Qt, QAbstractTableModel, pyqtSignal
34
- from cflib.localization import LighthouseBsGeoEstimator
35
34
  from cflib.localization import LighthouseSweepAngleAverageReader
36
35
  from cflib.crazyflie.mem import LighthouseBsGeometry
37
36
  from cfclient.ui.wizards.lighthouse_geo_bs_estimation_wizard import LighthouseBasestationGeometryWizard
@@ -138,13 +137,6 @@ class LighthouseBsGeometryDialog(QtWidgets.QWidget, basestation_geometry_widget_
138
137
  self._lighthouse_tab = lighthouse_tab
139
138
 
140
139
  self._estimate_geometry_button.clicked.connect(self._estimate_geometry_button_clicked)
141
- self._simple_estimator = LighthouseBsGeoEstimator()
142
- self._estimate_geometry_simple_button.clicked.connect(self._estimate_geometry_simple_button_clicked)
143
- try:
144
- if not self._simple_estimator.is_available():
145
- self._estimate_geometry_simple_button.setEnabled(False)
146
- except Exception as e:
147
- print(e)
148
140
 
149
141
  self._write_to_cf_button.clicked.connect(self._write_to_cf_button_clicked)
150
142
 
@@ -205,10 +197,6 @@ class LighthouseBsGeometryDialog(QtWidgets.QWidget, basestation_geometry_widget_
205
197
  self._base_station_geometry_wizard.show()
206
198
  self.hide()
207
199
 
208
- def _estimate_geometry_simple_button_clicked(self):
209
- self._sweep_angle_reader.start_angle_collection()
210
- self._update_ui()
211
-
212
200
  def _write_to_cf_button_clicked(self):
213
201
  if len(self._newly_estimated_geometry) > 0:
214
202
  self._lighthouse_tab.write_and_store_geometry(self._newly_estimated_geometry)
@@ -41,13 +41,6 @@
41
41
  </property>
42
42
  </spacer>
43
43
  </item>
44
- <item>
45
- <widget class="QPushButton" name="_estimate_geometry_simple_button">
46
- <property name="text">
47
- <string>Estimate Geometry Simple</string>
48
- </property>
49
- </widget>
50
- </item>
51
44
  </layout>
52
45
  </item>
53
46
  <item>
Binary file
Binary file
Binary file
Binary file
Binary file
cfclient/ui/main.py CHANGED
@@ -227,7 +227,7 @@ class MainUI(QtWidgets.QMainWindow, main_window_class):
227
227
  self.linkQualityBar.setTextVisible(False)
228
228
 
229
229
  # Connect link quality feedback
230
- self.cf.link_quality_updated.add_callback(self.linkQualitySignal.emit)
230
+ self.cf.link_statistics.link_quality_updated.add_callback(self.linkQualitySignal.emit)
231
231
  self.linkQualitySignal.connect(
232
232
  lambda percentage: self.linkQualityBar.setValue(int(percentage)))
233
233
 
@@ -683,8 +683,8 @@ class MainUI(QtWidgets.QMainWindow, main_window_class):
683
683
  if e.errno == 13: # Permission denied
684
684
  link = "<a href='https://www.bitcraze.io/documentation/repository/crazyflie-lib-python/master/installation/usb_permissions/'>Install USB Permissions</a>" # noqa
685
685
  msg = QMessageBox()
686
- msg.setIcon(QMessageBox.Information)
687
- msg.setTextFormat(Qt.RichText)
686
+ msg.setIcon(QMessageBox.Icon.Information)
687
+ msg.setTextFormat(Qt.TextFormat.RichText)
688
688
  msg.setText("Could not access Crazyradio")
689
689
  msg.setInformativeText(link)
690
690
  msg.setWindowTitle("Crazyradio permissions")
cfclient/ui/main.ui CHANGED
@@ -545,7 +545,7 @@
545
545
  <bool>false</bool>
546
546
  </property>
547
547
  <property name="text">
548
- <string>Configure 2.X</string>
548
+ <string>Configure 2.x</string>
549
549
  </property>
550
550
  <property name="menuRole">
551
551
  <enum>QAction::NoRole</enum>