cfclient 2017.4__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.
- cfclient/__init__.py +16 -11
- cfclient/configs/config.json +4 -3
- cfclient/configs/input/Generic_OS_X.json +1 -0
- cfclient/configs/input/Joystick.json +1 -0
- cfclient/configs/input/PS3_Mode_1.json +1 -0
- cfclient/configs/input/PS3_Mode_2.json +1 -0
- cfclient/configs/input/PS3_Mode_3.json +1 -0
- cfclient/configs/input/PS4_Mode_1.json +1 -0
- cfclient/configs/input/PS4_Mode_2.json +1 -0
- cfclient/configs/input/PS4_shoulder_btns_yaw.json +1 -0
- cfclient/configs/input/xbox360_mode1.json +1 -0
- cfclient/configs/log/PID_tuning/Attitude.json +46 -0
- cfclient/configs/log/PID_tuning/Attitude_rate.json +46 -0
- cfclient/configs/log/PID_tuning/Position.json +46 -0
- cfclient/configs/log/PID_tuning/Velocity.json +46 -0
- cfclient/configs/log/PID_tuning_components/Pitch.json +22 -0
- cfclient/configs/log/PID_tuning_components/Pitch_rate.json +22 -0
- cfclient/configs/log/PID_tuning_components/Position_x.json +22 -0
- cfclient/configs/log/PID_tuning_components/Position_y.json +22 -0
- cfclient/configs/log/PID_tuning_components/Position_z.json +22 -0
- cfclient/configs/log/PID_tuning_components/Roll.json +22 -0
- cfclient/configs/log/PID_tuning_components/Roll_rate.json +22 -0
- cfclient/configs/log/PID_tuning_components/Velocity_x.json +22 -0
- cfclient/configs/log/PID_tuning_components/Velocity_y.json +22 -0
- cfclient/configs/log/PID_tuning_components/Velocity_z.json +22 -0
- cfclient/configs/log/PID_tuning_components/Yaw.json +22 -0
- cfclient/configs/log/PID_tuning_components/Yaw_rate.json +22 -0
- cfclient/gui.py +44 -9
- cfclient/headless.py +3 -12
- cfclient/resources/log_param_doc.json +1 -0
- cfclient/ui/connectivity_manager.py +198 -0
- cfclient/ui/dialogs/about.py +53 -36
- cfclient/ui/dialogs/about.ui +23 -3
- cfclient/ui/dialogs/anchor_position_dialog.py +252 -0
- cfclient/ui/dialogs/anchor_position_dialog.ui +138 -0
- cfclient/ui/dialogs/basestation_mode_dialog.py +185 -0
- cfclient/ui/dialogs/basestation_mode_dialog.ui +186 -0
- cfclient/ui/dialogs/bootloader.py +448 -85
- cfclient/ui/dialogs/bootloader.ui +387 -134
- cfclient/ui/dialogs/cf2config.py +4 -4
- cfclient/ui/dialogs/cf2config.ui +3 -4
- cfclient/ui/dialogs/inputconfigdialogue.py +24 -19
- cfclient/ui/dialogs/inputconfigdialogue.ui +53 -30
- cfclient/ui/dialogs/lighthouse_bs_geometry_dialog.py +220 -0
- cfclient/ui/dialogs/lighthouse_bs_geometry_dialog.ui +110 -0
- cfclient/ui/dialogs/lighthouse_system_type_dialog.py +93 -0
- cfclient/ui/dialogs/lighthouse_system_type_dialog.ui +121 -0
- cfclient/ui/dialogs/logconfigdialogue.py +401 -101
- cfclient/ui/dialogs/logconfigdialogue.ui +117 -72
- cfclient/ui/icons/bl.webp +0 -0
- cfclient/ui/icons/bolt.webp +0 -0
- cfclient/ui/icons/cf21.webp +0 -0
- cfclient/ui/icons/checkmark_black.png +0 -0
- cfclient/ui/icons/checkmark_white.png +0 -0
- cfclient/ui/icons/create.png +0 -0
- cfclient/ui/icons/delete.png +0 -0
- cfclient/ui/icons/flapper.webp +0 -0
- cfclient/ui/icons/tag.webp +0 -0
- cfclient/ui/main.py +328 -258
- cfclient/ui/main.ui +184 -80
- cfclient/ui/pluginhelper.py +7 -1
- cfclient/ui/pose_logger.py +116 -0
- cfclient/ui/tab_toolbox.py +208 -0
- cfclient/ui/tabs/ColorLEDTab.py +752 -0
- cfclient/ui/tabs/ConsoleTab.py +48 -13
- cfclient/ui/{toolboxes → tabs}/CrtpSharkToolbox.py +19 -34
- cfclient/ui/tabs/ExampleTab.py +9 -16
- cfclient/ui/tabs/FlightTab.py +437 -325
- cfclient/ui/tabs/GpsTab.py +14 -20
- cfclient/ui/tabs/LEDRingTab.py +277 -0
- cfclient/ui/tabs/LogBlockDebugTab.py +20 -27
- cfclient/ui/tabs/LogBlockTab.py +35 -35
- cfclient/ui/tabs/LogClientTab.py +85 -0
- cfclient/ui/tabs/LogTab.py +50 -27
- cfclient/ui/tabs/ParamTab.py +443 -57
- cfclient/ui/tabs/PlotTab.py +23 -25
- cfclient/ui/tabs/TuningTab.py +292 -0
- cfclient/ui/tabs/__init__.py +12 -2
- cfclient/ui/tabs/colorLEDTab.ui +624 -0
- cfclient/ui/tabs/consoleTab.ui +46 -0
- cfclient/ui/tabs/flightActionContainer.ui +103 -0
- cfclient/ui/tabs/flightTab.ui +724 -237
- cfclient/ui/tabs/{ledTab.ui → ledRingTab.ui} +63 -46
- cfclient/ui/tabs/lighthouse_tab.py +714 -0
- cfclient/ui/tabs/lighthouse_tab.ui +430 -0
- cfclient/ui/tabs/locopositioning_tab.py +606 -389
- cfclient/ui/tabs/locopositioning_tab.ui +370 -253
- cfclient/ui/tabs/logClientTab.ui +52 -0
- cfclient/ui/tabs/logTab.ui +1 -1
- cfclient/ui/tabs/paramTab.ui +204 -3
- cfclient/ui/tabs/tuningTab.ui +773 -0
- cfclient/ui/widgets/ai.py +37 -39
- cfclient/ui/widgets/hexspinbox.py +16 -10
- cfclient/ui/widgets/plotter.ui +39 -47
- cfclient/ui/widgets/plotwidget.py +57 -22
- cfclient/ui/widgets/super_slider.py +112 -0
- cfclient/ui/wizards/__init__.py +0 -0
- cfclient/ui/wizards/bslh_1.png +0 -0
- cfclient/ui/wizards/bslh_2.png +0 -0
- cfclient/ui/wizards/bslh_3.png +0 -0
- cfclient/ui/wizards/bslh_4.png +0 -0
- cfclient/ui/wizards/bslh_5.png +0 -0
- cfclient/ui/wizards/lighthouse_geo_bs_estimation_wizard.py +465 -0
- cfclient/utils/config_manager.py +5 -4
- cfclient/utils/input/__init__.py +77 -19
- cfclient/utils/input/inputinterfaces/wiimote.py +2 -2
- cfclient/utils/input/inputreaderinterface.py +17 -7
- cfclient/utils/input/inputreaders/__init__.py +17 -0
- cfclient/utils/logconfigreader.py +245 -25
- cfclient/utils/logdatawriter.py +3 -1
- cfclient/utils/periodictimer.py +1 -1
- cfclient/utils/ui.py +336 -0
- cfclient/utils/zmq_led_driver.py +5 -0
- cfclient/utils/zmq_param.py +6 -0
- cfclient/version.py +34 -1
- cfclient-2025.12.1.dist-info/METADATA +70 -0
- cfclient-2025.12.1.dist-info/RECORD +152 -0
- {cfclient-2017.4.dist-info → cfclient-2025.12.1.dist-info}/WHEEL +1 -1
- {cfclient-2017.4.dist-info → cfclient-2025.12.1.dist-info}/entry_points.txt +0 -1
- cfclient-2025.12.1.dist-info/licenses/LICENSE.txt +350 -0
- {cfclient-2017.4.dist-info → cfclient-2025.12.1.dist-info}/top_level.txt +1 -0
- cfconfig/Makefile +51 -0
- cfconfig/configblock.py +111 -0
- cfloader/__init__.py +41 -55
- cfzmq/__init__.py +22 -14
- cfclient/ui/dialogs/cf1config.py +0 -265
- cfclient/ui/dialogs/cf1config.ui +0 -260
- cfclient/ui/tab.py +0 -96
- cfclient/ui/tabs/LEDTab.py +0 -169
- cfclient/ui/toolboxes/ConsoleToolbox.py +0 -69
- cfclient/ui/toolboxes/DebugDriverToolbox.py +0 -107
- cfclient/ui/toolboxes/__init__.py +0 -45
- cfclient/ui/toolboxes/consoleToolbox.ui +0 -62
- cfclient/ui/toolboxes/debugDriverToolbox.ui +0 -86
- cfclient-2017.4.dist-info/DESCRIPTION.rst +0 -3
- cfclient-2017.4.dist-info/METADATA +0 -22
- cfclient-2017.4.dist-info/RECORD +0 -104
- cfclient-2017.4.dist-info/metadata.json +0 -1
- /cfclient/{icon-256.png → ui/icons/icon-256.png} +0 -0
- /cfclient/ui/{toolboxes → tabs}/crtpSharkToolbox.ui +0 -0
cfclient/ui/tabs/GpsTab.py
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
|
|
8
8
|
# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
|
|
9
9
|
#
|
|
10
|
-
# Copyright (C) 2011-
|
|
10
|
+
# Copyright (C) 2011-2023 Bitcraze AB
|
|
11
11
|
#
|
|
12
12
|
# Crazyflie Nano Quadcopter Client
|
|
13
13
|
#
|
|
@@ -31,15 +31,15 @@ pre-configured.
|
|
|
31
31
|
import logging
|
|
32
32
|
|
|
33
33
|
import cfclient
|
|
34
|
-
from
|
|
35
|
-
from
|
|
36
|
-
from cfclient.ui.
|
|
34
|
+
from PyQt6.QtCore import pyqtSignal
|
|
35
|
+
from PyQt6.QtWidgets import QMessageBox
|
|
36
|
+
from cfclient.ui.tab_toolbox import TabToolbox
|
|
37
37
|
from cflib.crazyflie.log import LogConfig
|
|
38
|
-
from
|
|
39
|
-
from
|
|
40
|
-
from
|
|
41
|
-
from
|
|
42
|
-
from
|
|
38
|
+
from PyQt6 import QtCore
|
|
39
|
+
from PyQt6 import QtGui
|
|
40
|
+
from PyQt6 import QtNetwork
|
|
41
|
+
from PyQt6 import QtWebKit
|
|
42
|
+
from PyQt6 import uic
|
|
43
43
|
|
|
44
44
|
__author__ = 'Bitcraze AB'
|
|
45
45
|
__all__ = ['GpsTab']
|
|
@@ -50,7 +50,7 @@ gps_tab_class = uic.loadUiType(cfclient.module_path +
|
|
|
50
50
|
"/ui/tabs/gpsTab.ui")[0]
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
class GpsTab(
|
|
53
|
+
class GpsTab(TabToolbox, gps_tab_class):
|
|
54
54
|
"""Tab for plotting logging data"""
|
|
55
55
|
|
|
56
56
|
_log_data_signal = pyqtSignal(int, object, object)
|
|
@@ -60,15 +60,9 @@ class GpsTab(Tab, gps_tab_class):
|
|
|
60
60
|
_connected_signal = pyqtSignal(str)
|
|
61
61
|
_console_signal = pyqtSignal(str)
|
|
62
62
|
|
|
63
|
-
def __init__(self,
|
|
64
|
-
super(GpsTab, self).__init__(
|
|
63
|
+
def __init__(self, helper):
|
|
64
|
+
super(GpsTab, self).__init__(helper, 'GPS')
|
|
65
65
|
self.setupUi(self)
|
|
66
|
-
|
|
67
|
-
self.tabName = "GPS"
|
|
68
|
-
self.menuName = "GPS"
|
|
69
|
-
|
|
70
|
-
self.tabWidget = tabWidget
|
|
71
|
-
self.helper = helper
|
|
72
66
|
self._cf = helper.cf
|
|
73
67
|
|
|
74
68
|
view = self.view = QtWebKit.QWebView()
|
|
@@ -95,9 +89,9 @@ class GpsTab(Tab, gps_tab_class):
|
|
|
95
89
|
self._disconnected_signal.connect(self._disconnected)
|
|
96
90
|
|
|
97
91
|
# Connect the callbacks from the Crazyflie API
|
|
98
|
-
self.
|
|
92
|
+
self._helper.cf.disconnected.add_callback(
|
|
99
93
|
self._disconnected_signal.emit)
|
|
100
|
-
self.
|
|
94
|
+
self._helper.cf.connected.add_callback(
|
|
101
95
|
self._connected_signal.emit)
|
|
102
96
|
|
|
103
97
|
self._max_speed = 0.0
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# || ____ _ __
|
|
5
|
+
# +------+ / __ )(_) /_______________ _____ ___
|
|
6
|
+
# | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
|
|
7
|
+
# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
|
|
8
|
+
# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
|
|
9
|
+
#
|
|
10
|
+
# Copyright (C) 2011-2025 Bitcraze AB
|
|
11
|
+
#
|
|
12
|
+
# Crazyflie Nano Quadcopter Client
|
|
13
|
+
#
|
|
14
|
+
# This program is free software; you can redistribute it and/or
|
|
15
|
+
# modify it under the terms of the GNU General Public License
|
|
16
|
+
# as published by the Free Software Foundation; either version 2
|
|
17
|
+
# of the License, or (at your option) any later version.
|
|
18
|
+
#
|
|
19
|
+
# This program is distributed in the hope that it will be useful,
|
|
20
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
21
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
22
|
+
# GNU General Public License for more details.
|
|
23
|
+
|
|
24
|
+
# You should have received a copy of the GNU General Public License
|
|
25
|
+
# along with this program; if not, write to the Free Software
|
|
26
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
27
|
+
# 02110-1301, USA.
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
Basic tab to be able to set (and test) colors in the LED-ring.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import logging
|
|
34
|
+
|
|
35
|
+
from PyQt6 import QtGui, uic
|
|
36
|
+
from PyQt6.QtCore import pyqtSignal
|
|
37
|
+
from PyQt6 import QtWidgets
|
|
38
|
+
|
|
39
|
+
import cfclient
|
|
40
|
+
from cfclient.ui.tab_toolbox import TabToolbox
|
|
41
|
+
|
|
42
|
+
from cflib.crazyflie.mem import MemoryElement
|
|
43
|
+
|
|
44
|
+
__author__ = 'Bitcraze AB'
|
|
45
|
+
__all__ = ['LEDRingTab']
|
|
46
|
+
|
|
47
|
+
logger = logging.getLogger(__name__)
|
|
48
|
+
|
|
49
|
+
led_ring_tab_class = uic.loadUiType(cfclient.module_path + "/ui/tabs/ledRingTab.ui")[0]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class LEDRingTab(TabToolbox, led_ring_tab_class):
|
|
53
|
+
"""Tab for plotting logging data"""
|
|
54
|
+
|
|
55
|
+
_connected_signal = pyqtSignal(str)
|
|
56
|
+
_disconnected_signal = pyqtSignal(str)
|
|
57
|
+
|
|
58
|
+
def __init__(self, helper):
|
|
59
|
+
super(LEDRingTab, self).__init__(helper, 'LED Ring')
|
|
60
|
+
self.setupUi(self)
|
|
61
|
+
|
|
62
|
+
# LED-ring effect dropdown and headlight checkbox
|
|
63
|
+
self._ledring_nbr_effects = 0
|
|
64
|
+
|
|
65
|
+
# Connect the headlight checkbox
|
|
66
|
+
self._led_ring_headlight.clicked.connect(
|
|
67
|
+
lambda enabled: self._helper.cf.param.set_value("ring.headlightEnable", int(enabled)))
|
|
68
|
+
|
|
69
|
+
# Update headlight when param changes
|
|
70
|
+
self._helper.cf.param.add_update_callback(
|
|
71
|
+
group="ring", name="headlightEnable",
|
|
72
|
+
cb=lambda name, checked: self._led_ring_headlight.setChecked(bool(int(checked))))
|
|
73
|
+
|
|
74
|
+
# Update LED-ring effect when param changes
|
|
75
|
+
self._helper.cf.param.add_update_callback(
|
|
76
|
+
group="ring", name="effect",
|
|
77
|
+
cb=self._ring_effect_updated)
|
|
78
|
+
|
|
79
|
+
# Populate dropdown when all params are updated
|
|
80
|
+
self._helper.cf.param.all_updated.add_callback(self._ring_populate_dropdown)
|
|
81
|
+
|
|
82
|
+
# Always wrap callbacks from Crazyflie API though QT Signal/Slots
|
|
83
|
+
# to avoid manipulating the UI when rendering it
|
|
84
|
+
self._connected_signal.connect(self._connected)
|
|
85
|
+
self._disconnected_signal.connect(self._disconnected)
|
|
86
|
+
|
|
87
|
+
# Connect the Crazyflie API callbacks to the signals
|
|
88
|
+
self._helper.cf.connected.add_callback(
|
|
89
|
+
self._connected_signal.emit)
|
|
90
|
+
|
|
91
|
+
self._helper.cf.disconnected.add_callback(
|
|
92
|
+
self._disconnected_signal.emit)
|
|
93
|
+
|
|
94
|
+
self._btns = [self._u1,
|
|
95
|
+
self._u2,
|
|
96
|
+
self._u3,
|
|
97
|
+
self._u4,
|
|
98
|
+
self._u5,
|
|
99
|
+
self._u6,
|
|
100
|
+
self._u7,
|
|
101
|
+
self._u8,
|
|
102
|
+
self._u9,
|
|
103
|
+
self._u10,
|
|
104
|
+
self._u11,
|
|
105
|
+
self._u12]
|
|
106
|
+
|
|
107
|
+
self._intensity = self._intensity_slider.value()
|
|
108
|
+
|
|
109
|
+
self._u1.clicked.connect(lambda: self._select(0))
|
|
110
|
+
self._u2.clicked.connect(lambda: self._select(1))
|
|
111
|
+
self._u3.clicked.connect(lambda: self._select(2))
|
|
112
|
+
self._u4.clicked.connect(lambda: self._select(3))
|
|
113
|
+
self._u5.clicked.connect(lambda: self._select(4))
|
|
114
|
+
self._u6.clicked.connect(lambda: self._select(5))
|
|
115
|
+
self._u7.clicked.connect(lambda: self._select(6))
|
|
116
|
+
self._u8.clicked.connect(lambda: self._select(7))
|
|
117
|
+
self._u9.clicked.connect(lambda: self._select(8))
|
|
118
|
+
self._u10.clicked.connect(lambda: self._select(9))
|
|
119
|
+
self._u11.clicked.connect(lambda: self._select(10))
|
|
120
|
+
self._u12.clicked.connect(lambda: self._select(11))
|
|
121
|
+
|
|
122
|
+
self._mem = None
|
|
123
|
+
|
|
124
|
+
self._intensity_slider.valueChanged.connect(self._intensity_change)
|
|
125
|
+
self._intensity_slider.valueChanged.connect(
|
|
126
|
+
self._intensity_spin.setValue)
|
|
127
|
+
self._intensity_spin.valueChanged.connect(
|
|
128
|
+
self._intensity_slider.setValue)
|
|
129
|
+
|
|
130
|
+
self._helper.inputDeviceReader.alt1_updated.add_callback(self.alt1_updated)
|
|
131
|
+
self._helper.inputDeviceReader.alt2_updated.add_callback(self.alt2_updated)
|
|
132
|
+
|
|
133
|
+
self._led_ring_effect.setEnabled(False)
|
|
134
|
+
self._led_ring_headlight.setEnabled(False)
|
|
135
|
+
|
|
136
|
+
def _select(self, nbr):
|
|
137
|
+
col = QtGui.QColor()
|
|
138
|
+
|
|
139
|
+
if self._mem:
|
|
140
|
+
led = self._mem.leds[nbr]
|
|
141
|
+
col = QtGui.QColor.fromRgb(led.r, led.g, led.b)
|
|
142
|
+
|
|
143
|
+
col = QtWidgets.QColorDialog.getColor(col)
|
|
144
|
+
|
|
145
|
+
if col.isValid() and self._mem:
|
|
146
|
+
r, g, b = col.red(), col.green(), col.blue()
|
|
147
|
+
self._mem.leds[nbr].set(r=r, g=g, b=b)
|
|
148
|
+
|
|
149
|
+
brightness = 0.299 * r + 0.587 * g + 0.114 * b
|
|
150
|
+
text_color = "white" if brightness < 128 else "black"
|
|
151
|
+
|
|
152
|
+
self.sender().setStyleSheet(
|
|
153
|
+
f"background-color: rgb({r}, {g}, {b}); color: {text_color};"
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
self._write_led_output()
|
|
157
|
+
|
|
158
|
+
def _intensity_change(self, value):
|
|
159
|
+
self._intensity = value
|
|
160
|
+
self._write_led_output()
|
|
161
|
+
|
|
162
|
+
def _write_led_output(self):
|
|
163
|
+
if self._mem:
|
|
164
|
+
for led in self._mem.leds:
|
|
165
|
+
led.intensity = self._intensity
|
|
166
|
+
self._mem.write_data(self._led_write_done)
|
|
167
|
+
else:
|
|
168
|
+
logger.info("No LED-ring memory found!")
|
|
169
|
+
|
|
170
|
+
def _led_write_done(self, mem, addr):
|
|
171
|
+
logger.info("LED write done callback")
|
|
172
|
+
|
|
173
|
+
def _connected(self, link_uri):
|
|
174
|
+
"""Callback when the Crazyflie has been connected"""
|
|
175
|
+
mems = self._helper.cf.mem.get_mems(MemoryElement.TYPE_DRIVER_LED)
|
|
176
|
+
if len(mems) > 0:
|
|
177
|
+
self._mem = mems[0]
|
|
178
|
+
logger.info(self._mem)
|
|
179
|
+
|
|
180
|
+
if self._mem:
|
|
181
|
+
for btn in self._btns:
|
|
182
|
+
btn.setEnabled(True)
|
|
183
|
+
btn.setStyleSheet("background-color: black; color: white")
|
|
184
|
+
self._intensity_slider.setEnabled(True)
|
|
185
|
+
self._intensity_spin.setEnabled(True)
|
|
186
|
+
|
|
187
|
+
self._led_ring_effect.setEnabled(True)
|
|
188
|
+
self._led_ring_headlight.setEnabled(True)
|
|
189
|
+
|
|
190
|
+
def _disconnected(self, link_uri):
|
|
191
|
+
"""Callback for when the Crazyflie has been disconnected"""
|
|
192
|
+
for btn in self._btns:
|
|
193
|
+
btn.setEnabled(False)
|
|
194
|
+
btn.setStyleSheet("background-color: none")
|
|
195
|
+
self._intensity_slider.setEnabled(False)
|
|
196
|
+
self._intensity_spin.setEnabled(False)
|
|
197
|
+
self._intensity_slider.setValue(100)
|
|
198
|
+
|
|
199
|
+
self._led_ring_effect.setEnabled(False)
|
|
200
|
+
self._led_ring_headlight.setEnabled(False)
|
|
201
|
+
|
|
202
|
+
def _ring_populate_dropdown(self):
|
|
203
|
+
try:
|
|
204
|
+
nbr = int(self._helper.cf.param.values["ring"]["neffect"])
|
|
205
|
+
current = int(self._helper.cf.param.values["ring"]["effect"])
|
|
206
|
+
except KeyError:
|
|
207
|
+
return
|
|
208
|
+
|
|
209
|
+
self._ring_effect = current
|
|
210
|
+
self._ledring_nbr_effects = nbr
|
|
211
|
+
|
|
212
|
+
hardcoded_names = {
|
|
213
|
+
0: "Off",
|
|
214
|
+
1: "White spinner",
|
|
215
|
+
2: "Color spinner",
|
|
216
|
+
3: "Tilt effect",
|
|
217
|
+
4: "Brightness effect",
|
|
218
|
+
5: "Color spinner 2",
|
|
219
|
+
6: "Double spinner",
|
|
220
|
+
7: "Solid color effect",
|
|
221
|
+
8: "Factory test",
|
|
222
|
+
9: "Battery status",
|
|
223
|
+
10: "Boat lights",
|
|
224
|
+
11: "Alert",
|
|
225
|
+
12: "Gravity",
|
|
226
|
+
13: "LED tab",
|
|
227
|
+
14: "Color fader",
|
|
228
|
+
15: "Link quality",
|
|
229
|
+
16: "Location server status",
|
|
230
|
+
17: "Sequencer",
|
|
231
|
+
18: "Lighthouse quality",
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
self._led_ring_effect.clear()
|
|
235
|
+
for i in range(nbr + 1):
|
|
236
|
+
name = "{}: ".format(i)
|
|
237
|
+
name += hardcoded_names.get(i, "N/A")
|
|
238
|
+
self._led_ring_effect.addItem(name, i)
|
|
239
|
+
|
|
240
|
+
self._led_ring_effect.currentIndexChanged.connect(self._ring_effect_changed)
|
|
241
|
+
self._led_ring_effect.setCurrentIndex(current)
|
|
242
|
+
self._led_ring_effect.setEnabled(int(self._helper.cf.param.values["deck"]["bcLedRing"]) == 1)
|
|
243
|
+
self._led_ring_headlight.setEnabled(int(self._helper.cf.param.values["deck"]["bcLedRing"]) == 1)
|
|
244
|
+
|
|
245
|
+
try:
|
|
246
|
+
self._helper.cf.param.set_value("ring.effect", "13")
|
|
247
|
+
self._led_ring_effect.setCurrentIndex(13)
|
|
248
|
+
self._ring_effect = 13
|
|
249
|
+
logger.info("Initialized LED ring to 'LED tab' mode (effect 13).")
|
|
250
|
+
except Exception as e:
|
|
251
|
+
logger.warning(f"Could not set LED tab effect on connect: {e}")
|
|
252
|
+
|
|
253
|
+
def _ring_effect_changed(self, index):
|
|
254
|
+
self._ring_effect = index
|
|
255
|
+
if index > -1:
|
|
256
|
+
i = self._led_ring_effect.itemData(index)
|
|
257
|
+
if i != int(self._helper.cf.param.values["ring"]["effect"]):
|
|
258
|
+
self._helper.cf.param.set_value("ring.effect", str(i))
|
|
259
|
+
|
|
260
|
+
if i == 13:
|
|
261
|
+
self._intensity_slider.setEnabled(True)
|
|
262
|
+
self._intensity_spin.setEnabled(True)
|
|
263
|
+
else:
|
|
264
|
+
self._intensity_slider.setEnabled(False)
|
|
265
|
+
self._intensity_spin.setEnabled(False)
|
|
266
|
+
|
|
267
|
+
def _ring_effect_updated(self, name, value):
|
|
268
|
+
if self._helper.cf.param.is_updated:
|
|
269
|
+
self._led_ring_effect.setCurrentIndex(int(value))
|
|
270
|
+
|
|
271
|
+
def alt1_updated(self, state):
|
|
272
|
+
if state:
|
|
273
|
+
new_index = (self._ring_effect+1) % (self._ledring_nbr_effects+1)
|
|
274
|
+
self._helper.cf.param.set_value("ring.effect", str(new_index))
|
|
275
|
+
|
|
276
|
+
def alt2_updated(self, state):
|
|
277
|
+
self._helper.cf.param.set_value("ring.headlightEnable", str(state))
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
|
|
8
8
|
# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
|
|
9
9
|
#
|
|
10
|
-
# Copyright (C) 2013 Bitcraze AB
|
|
10
|
+
# Copyright (C) 2013-2023 Bitcraze AB
|
|
11
11
|
#
|
|
12
12
|
# Crazyflie Nano Quadcopter Client
|
|
13
13
|
#
|
|
@@ -30,20 +30,19 @@ Shows all the parameters available in the Crazyflie and also gives the ability
|
|
|
30
30
|
to edit them.
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
-
from
|
|
34
|
-
from
|
|
33
|
+
from PyQt6 import QtWidgets, uic
|
|
34
|
+
from PyQt6.QtCore import Qt, pyqtSignal
|
|
35
35
|
|
|
36
36
|
import cfclient
|
|
37
|
-
from cfclient.ui.
|
|
37
|
+
from cfclient.ui.tab_toolbox import TabToolbox
|
|
38
38
|
|
|
39
39
|
__author__ = 'Bitcraze AB'
|
|
40
40
|
__all__ = ['LogBlockDebugTab']
|
|
41
41
|
|
|
42
|
-
logblock_tab_class = uic.loadUiType(cfclient.module_path +
|
|
43
|
-
"/ui/tabs/logBlockDebugTab.ui")[0]
|
|
42
|
+
logblock_tab_class = uic.loadUiType(cfclient.module_path + "/ui/tabs/logBlockDebugTab.ui")[0]
|
|
44
43
|
|
|
45
44
|
|
|
46
|
-
class LogBlockDebugTab(
|
|
45
|
+
class LogBlockDebugTab(TabToolbox, logblock_tab_class):
|
|
47
46
|
"""
|
|
48
47
|
Used to show debug-information about log status.
|
|
49
48
|
"""
|
|
@@ -51,16 +50,10 @@ class LogBlockDebugTab(Tab, logblock_tab_class):
|
|
|
51
50
|
_blocks_updated_signal = pyqtSignal(object, bool)
|
|
52
51
|
_disconnected_signal = pyqtSignal(str)
|
|
53
52
|
|
|
54
|
-
def __init__(self,
|
|
55
|
-
super(LogBlockDebugTab, self).__init__(
|
|
53
|
+
def __init__(self, helper):
|
|
54
|
+
super(LogBlockDebugTab, self).__init__(helper, 'Log Blocks Debugging')
|
|
56
55
|
self.setupUi(self)
|
|
57
56
|
|
|
58
|
-
self.tabName = "Log Blocks Debugging"
|
|
59
|
-
self.menuName = "Log Blocks Debugging"
|
|
60
|
-
|
|
61
|
-
self._helper = helper
|
|
62
|
-
self.tabWidget = tabWidget
|
|
63
|
-
|
|
64
57
|
self._helper.cf.log.block_added_cb.add_callback(self._block_added)
|
|
65
58
|
self._disconnected_signal.connect(self._disconnected)
|
|
66
59
|
self._helper.cf.disconnected.add_callback(
|
|
@@ -70,7 +63,7 @@ class LogBlockDebugTab(Tab, logblock_tab_class):
|
|
|
70
63
|
self._block_tree.setHeaderLabels(
|
|
71
64
|
['Id', 'Name', 'Period (ms)', 'Added', 'Started', 'Error',
|
|
72
65
|
'Contents'])
|
|
73
|
-
self._block_tree.sortItems(0,
|
|
66
|
+
self._block_tree.sortItems(0, Qt.SortOrder.AscendingOrder)
|
|
74
67
|
|
|
75
68
|
def _block_added(self, block):
|
|
76
69
|
"""Callback when a new logblock has been created"""
|
|
@@ -82,19 +75,19 @@ class LogBlockDebugTab(Tab, logblock_tab_class):
|
|
|
82
75
|
self._block_tree.clear()
|
|
83
76
|
for block in self._helper.cf.log.log_blocks:
|
|
84
77
|
item = QtWidgets.QTreeWidgetItem()
|
|
85
|
-
item.setFlags(Qt.ItemIsEnabled |
|
|
86
|
-
Qt.ItemIsSelectable)
|
|
87
|
-
item.setData(0, Qt.DisplayRole, block.id)
|
|
88
|
-
item.setData(1, Qt.EditRole, block.name)
|
|
89
|
-
item.setData(2, Qt.DisplayRole, (block.period_in_ms))
|
|
90
|
-
item.setData(3, Qt.DisplayRole, block.added)
|
|
91
|
-
item.setData(4, Qt.EditRole, block.started)
|
|
92
|
-
item.setData(5, Qt.EditRole, block.err_no)
|
|
78
|
+
item.setFlags(Qt.ItemFlag.ItemIsEnabled |
|
|
79
|
+
Qt.ItemFlag.ItemIsSelectable)
|
|
80
|
+
item.setData(0, Qt.ItemDataRole.DisplayRole, block.id)
|
|
81
|
+
item.setData(1, Qt.ItemDataRole.EditRole, block.name)
|
|
82
|
+
item.setData(2, Qt.ItemDataRole.DisplayRole, (block.period_in_ms))
|
|
83
|
+
item.setData(3, Qt.ItemDataRole.DisplayRole, block.added)
|
|
84
|
+
item.setData(4, Qt.ItemDataRole.EditRole, block.started)
|
|
85
|
+
item.setData(5, Qt.ItemDataRole.EditRole, block.err_no)
|
|
93
86
|
for var in block.variables:
|
|
94
87
|
subItem = QtWidgets.QTreeWidgetItem()
|
|
95
|
-
subItem.setFlags(Qt.ItemIsEnabled |
|
|
96
|
-
Qt.ItemIsSelectable)
|
|
97
|
-
subItem.setData(6, Qt.EditRole, var.name)
|
|
88
|
+
subItem.setFlags(Qt.ItemFlag.ItemIsEnabled |
|
|
89
|
+
Qt.ItemFlag.ItemIsSelectable)
|
|
90
|
+
subItem.setData(6, Qt.ItemDataRole.EditRole, var.name)
|
|
98
91
|
item.addChild(subItem)
|
|
99
92
|
|
|
100
93
|
self._block_tree.addTopLevelItem(item)
|
cfclient/ui/tabs/LogBlockTab.py
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
|
|
8
8
|
# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
|
|
9
9
|
#
|
|
10
|
-
# Copyright (C) 2013 Bitcraze AB
|
|
10
|
+
# Copyright (C) 2013-2023 Bitcraze AB
|
|
11
11
|
#
|
|
12
12
|
# Crazyflie Nano Quadcopter Client
|
|
13
13
|
#
|
|
@@ -31,25 +31,24 @@ This tab shows all log blocks that are registered and can be used to start the
|
|
|
31
31
|
logging and also to write the logging data to file.
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
|
-
from
|
|
35
|
-
from
|
|
34
|
+
from PyQt6 import uic
|
|
35
|
+
from PyQt6.QtCore import Qt, pyqtSignal
|
|
36
36
|
|
|
37
37
|
import cfclient
|
|
38
|
-
from cfclient.ui.
|
|
38
|
+
from cfclient.ui.tab_toolbox import TabToolbox
|
|
39
39
|
|
|
40
40
|
import logging
|
|
41
41
|
|
|
42
|
-
from
|
|
43
|
-
from
|
|
44
|
-
from
|
|
42
|
+
from PyQt6.QtWidgets import QApplication, QStyledItemDelegate
|
|
43
|
+
from PyQt6.QtWidgets import QAbstractItemView, QStyleOptionButton, QStyle
|
|
44
|
+
from PyQt6.QtCore import QAbstractItemModel, QModelIndex
|
|
45
45
|
|
|
46
46
|
from cfclient.utils.logdatawriter import LogWriter
|
|
47
47
|
|
|
48
48
|
__author__ = 'Bitcraze AB'
|
|
49
49
|
__all__ = ['LogBlockTab']
|
|
50
50
|
|
|
51
|
-
logblock_tab_class = uic.loadUiType(
|
|
52
|
-
cfclient.module_path + "/ui/tabs/logBlockTab.ui")[0]
|
|
51
|
+
logblock_tab_class = uic.loadUiType(cfclient.module_path + "/ui/tabs/logBlockTab.ui")[0]
|
|
53
52
|
|
|
54
53
|
logger = logging.getLogger(__name__)
|
|
55
54
|
|
|
@@ -176,6 +175,7 @@ class LogBlockModel(QAbstractItemModel):
|
|
|
176
175
|
def add_block(self, block, connected_ts):
|
|
177
176
|
self._nodes.append(LogBlockItem(block, self, connected_ts))
|
|
178
177
|
self.layoutChanged.emit()
|
|
178
|
+
self._nodes.sort(key=lambda conf: conf.name.lower())
|
|
179
179
|
|
|
180
180
|
def refresh(self):
|
|
181
181
|
"""Force a refresh of the view though the model"""
|
|
@@ -220,7 +220,7 @@ class LogBlockModel(QAbstractItemModel):
|
|
|
220
220
|
|
|
221
221
|
def headerData(self, section, orientation, role):
|
|
222
222
|
"""Re-implemented method to get the headers"""
|
|
223
|
-
if role == Qt.DisplayRole:
|
|
223
|
+
if role == Qt.ItemDataRole.DisplayRole:
|
|
224
224
|
return self._column_headers[section]
|
|
225
225
|
|
|
226
226
|
def rowCount(self, parent):
|
|
@@ -250,20 +250,20 @@ class LogBlockModel(QAbstractItemModel):
|
|
|
250
250
|
node = index.internalPointer()
|
|
251
251
|
parent = node.parent
|
|
252
252
|
if parent:
|
|
253
|
-
if role == Qt.DisplayRole and index.column() == 5:
|
|
253
|
+
if role == Qt.ItemDataRole.DisplayRole and index.column() == 5:
|
|
254
254
|
return node.name
|
|
255
|
-
elif not parent and role == Qt.DisplayRole and index.column() == 5:
|
|
255
|
+
elif not parent and role == Qt.ItemDataRole.DisplayRole and index.column() == 5:
|
|
256
256
|
return node.var_list()
|
|
257
|
-
elif not parent and role == Qt.DisplayRole:
|
|
257
|
+
elif not parent and role == Qt.ItemDataRole.DisplayRole:
|
|
258
258
|
if index.column() == 0:
|
|
259
259
|
return node.id
|
|
260
260
|
if index.column() == 1:
|
|
261
261
|
return node.name
|
|
262
262
|
if index.column() == 2:
|
|
263
263
|
return str(node.period)
|
|
264
|
-
if role == Qt.TextAlignmentRole and \
|
|
264
|
+
if role == Qt.ItemDataRole.TextAlignmentRole and \
|
|
265
265
|
(index.column() == 4 or index.column() == 3):
|
|
266
|
-
return Qt.AlignHCenter | Qt.AlignVCenter
|
|
266
|
+
return Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter
|
|
267
267
|
|
|
268
268
|
return None
|
|
269
269
|
|
|
@@ -286,31 +286,37 @@ class CheckboxDelegate(QStyledItemDelegate):
|
|
|
286
286
|
col = index.column()
|
|
287
287
|
if not item.parent and (col == 3 or col == 4):
|
|
288
288
|
s = QStyleOptionButton()
|
|
289
|
-
checkbox_rect = QApplication.style().
|
|
290
|
-
subElementRect(QStyle.SE_CheckBoxIndicator, option)
|
|
289
|
+
checkbox_rect = QApplication.style().subElementRect(QStyle.SubElement.SE_CheckBoxIndicator, option)
|
|
291
290
|
s.rect = option.rect
|
|
292
|
-
center_offset = s.rect.width() / 2 - checkbox_rect.width() / 2
|
|
291
|
+
center_offset = int(s.rect.width() / 2 - checkbox_rect.width() / 2)
|
|
293
292
|
s.rect.adjust(center_offset, 0, 0, 0)
|
|
294
293
|
|
|
295
294
|
if col == 3:
|
|
296
295
|
if not item.doing_transaction():
|
|
297
|
-
s.state = QStyle.State_Enabled
|
|
296
|
+
s.state = QStyle.StateFlag.State_Enabled
|
|
298
297
|
if item.logging_started():
|
|
299
|
-
s.state |= QStyle.State_On
|
|
298
|
+
s.state |= QStyle.StateFlag.State_On
|
|
300
299
|
|
|
301
300
|
if col == 4:
|
|
302
|
-
s.state = QStyle.State_Enabled
|
|
301
|
+
s.state = QStyle.StateFlag.State_Enabled
|
|
303
302
|
if item.writing_to_file():
|
|
304
|
-
s.state |= QStyle.State_On
|
|
305
|
-
|
|
306
|
-
QApplication.style().drawControl(
|
|
307
|
-
QStyle.CE_CheckBox, s, painter)
|
|
303
|
+
s.state |= QStyle.StateFlag.State_On
|
|
308
304
|
|
|
305
|
+
self._paint_checkbox(s, painter)
|
|
309
306
|
else:
|
|
310
307
|
super(CheckboxDelegate, self).paint(painter, option, index)
|
|
311
308
|
|
|
309
|
+
def _paint_checkbox(self, style, painter):
|
|
310
|
+
QApplication.style().drawControl(QStyle.ControlElement.CE_CheckBox, style, painter)
|
|
311
|
+
|
|
312
|
+
def _paint_checkbox_osx_workaround(self, style, painter):
|
|
313
|
+
painter.save()
|
|
314
|
+
painter.translate(style.rect.topLeft())
|
|
315
|
+
QApplication.style().drawControl(QStyle.ControlElement.CE_CheckBox, style, painter)
|
|
316
|
+
painter.restore()
|
|
317
|
+
|
|
312
318
|
|
|
313
|
-
class LogBlockTab(
|
|
319
|
+
class LogBlockTab(TabToolbox, logblock_tab_class):
|
|
314
320
|
"""
|
|
315
321
|
Used to show debug-information about logblock status.
|
|
316
322
|
"""
|
|
@@ -318,17 +324,11 @@ class LogBlockTab(Tab, logblock_tab_class):
|
|
|
318
324
|
_blocks_updated_signal = pyqtSignal(bool)
|
|
319
325
|
_disconnected_signal = pyqtSignal(str)
|
|
320
326
|
|
|
321
|
-
def __init__(self,
|
|
327
|
+
def __init__(self, helper):
|
|
322
328
|
"""Initialize the tab"""
|
|
323
|
-
super(LogBlockTab, self).__init__(
|
|
329
|
+
super(LogBlockTab, self).__init__(helper, 'Log Blocks')
|
|
324
330
|
self.setupUi(self)
|
|
325
331
|
|
|
326
|
-
self.tabName = "Log Blocks"
|
|
327
|
-
self.menuName = "Log Blocks"
|
|
328
|
-
|
|
329
|
-
self._helper = helper
|
|
330
|
-
self.tabWidget = tabWidget
|
|
331
|
-
|
|
332
332
|
self._helper.cf.log.block_added_cb.add_callback(self._block_added)
|
|
333
333
|
self._disconnected_signal.connect(self._disconnected)
|
|
334
334
|
self._helper.cf.disconnected.add_callback(
|
|
@@ -338,7 +338,7 @@ class LogBlockTab(Tab, logblock_tab_class):
|
|
|
338
338
|
self._block_tree.setModel(self._model)
|
|
339
339
|
self._block_tree.clicked.connect(self._model.clicked)
|
|
340
340
|
self._block_tree.setItemDelegate(CheckboxDelegate())
|
|
341
|
-
self._block_tree.setSelectionMode(QAbstractItemView.NoSelection)
|
|
341
|
+
self._block_tree.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
|
|
342
342
|
|
|
343
343
|
def _block_added(self, block):
|
|
344
344
|
"""Callback from logging layer when a new block is added"""
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# || ____ _ __
|
|
5
|
+
# +------+ / __ )(_) /_______________ _____ ___
|
|
6
|
+
# | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
|
|
7
|
+
# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
|
|
8
|
+
# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
|
|
9
|
+
#
|
|
10
|
+
# Copyright (C) 2011-2023 Bitcraze AB
|
|
11
|
+
#
|
|
12
|
+
# Crazyflie Nano Quadcopter Client
|
|
13
|
+
#
|
|
14
|
+
# This program is free software; you can redistribute it and/or
|
|
15
|
+
# modify it under the terms of the GNU General Public License
|
|
16
|
+
# as published by the Free Software Foundation; either version 2
|
|
17
|
+
# of the License, or (at your option) any later version.
|
|
18
|
+
#
|
|
19
|
+
# This program is distributed in the hope that it will be useful,
|
|
20
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
21
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
22
|
+
# GNU General Public License for more details.
|
|
23
|
+
|
|
24
|
+
# You should have received a copy of the GNU General Public License along with
|
|
25
|
+
# this program; if not, write to the Free Software Foundation, Inc.,
|
|
26
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
Shows information from the Python logging framework
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
import logging
|
|
33
|
+
|
|
34
|
+
from PyQt6 import uic
|
|
35
|
+
from PyQt6.QtCore import pyqtSignal
|
|
36
|
+
|
|
37
|
+
import cfclient
|
|
38
|
+
from cfclient.ui.tab_toolbox import TabToolbox
|
|
39
|
+
|
|
40
|
+
__author__ = 'Bitcraze AB'
|
|
41
|
+
__all__ = ['LogClientTab']
|
|
42
|
+
|
|
43
|
+
logger = logging.getLogger(__name__)
|
|
44
|
+
|
|
45
|
+
log_client_tab_class = uic.loadUiType(cfclient.module_path + "/ui/tabs/logClientTab.ui")[0]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class LogHandler(logging.StreamHandler):
|
|
49
|
+
def __init__(self, signal):
|
|
50
|
+
logging.StreamHandler.__init__(self)
|
|
51
|
+
self._signal = signal
|
|
52
|
+
|
|
53
|
+
def emit(self, record):
|
|
54
|
+
fmt = '%(levelname)s:%(name)s:%(message)s'
|
|
55
|
+
formatter = logging.Formatter(fmt)
|
|
56
|
+
#
|
|
57
|
+
# Calling .emit() on the signal will make the callback
|
|
58
|
+
# we registered in LogClientTab run.
|
|
59
|
+
#
|
|
60
|
+
self._signal.emit(formatter.format(record))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class LogClientTab(TabToolbox, log_client_tab_class):
|
|
64
|
+
"""
|
|
65
|
+
A tab for showing client logging information, such
|
|
66
|
+
as USB Gamepad connections or scan feedback.
|
|
67
|
+
"""
|
|
68
|
+
_update = pyqtSignal(str)
|
|
69
|
+
|
|
70
|
+
def __init__(self, helper):
|
|
71
|
+
super(LogClientTab, self).__init__(helper, 'Log Client')
|
|
72
|
+
self.setupUi(self)
|
|
73
|
+
|
|
74
|
+
self._update.connect(self.printText)
|
|
75
|
+
self._clearButton.clicked.connect(self.clear)
|
|
76
|
+
|
|
77
|
+
cflogger = logging.getLogger(None)
|
|
78
|
+
cflogger.addHandler(LogHandler(self._update))
|
|
79
|
+
|
|
80
|
+
def printText(self, text):
|
|
81
|
+
logger.debug("[%s]", text)
|
|
82
|
+
self.syslog.insertPlainText(text + '\n')
|
|
83
|
+
|
|
84
|
+
def clear(self):
|
|
85
|
+
self.syslog.clear()
|