From 57a5e6be6d581710d7eeaadc91c3b5742fb81b53 Mon Sep 17 00:00:00 2001 From: Christian Kolset Date: Tue, 11 Aug 2026 10:40:12 -0600 Subject: Fix native-style Qt warning; add a few tooltips; trim Namespace hint text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause of "QFont::setPointSize: Point size <= 0 (-1)" on some dropdowns: the app never sets an explicit widget style, so it defaults to native windowsvista, whose popup code calls setPointSize() on fonts resolved from our QSS's pixel-based font-size (pointSize() is -1 by design for px fonts). Tried app.setStyle("Fusion") first — silences it, but Fusion doesn't render buttons/dropdowns to match the QSS the way the native style does. Kept native style, filtered just that one message via qInstallMessageHandler instead — it's cosmetic Qt console noise (the rejected setPointSize call is a no-op, doesn't affect rendering), not a real bug. Also adds a handful of tooltips (Control Editor's Check Syntax/Cancel/ Create Control, device Configure dialog's Close, main toolbar's View/ Configure/RUN/LOG/Settings, a few Control Panel widgets) from an in-progress app-wide tooltip pass, paused partway through by request — remaining buttons are being done manually. Co-Authored-By: Claude Sonnet 5 --- main.py | 20 ++++++++++++++++++++ ui/config_dialog.py | 1 + ui/control_editor.py | 5 ++++- ui/control_panel.py | 5 +++++ ui/main_window.py | 5 +++++ ui/namespace_panel.py | 3 +-- 6 files changed, 36 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index dff00bd..26fcaaf 100644 --- a/main.py +++ b/main.py @@ -12,10 +12,30 @@ import sys, os sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from PyQt6.QtWidgets import QApplication +from PyQt6.QtCore import qInstallMessageHandler, QtMsgType from ui.main_window import MainWindow +def _qt_message_handler(msg_type, context, message): + """Silence one specific, harmless Qt warning: the native windowsvista + style's combo-box/menu popup code calls QFont::setPointSize() on a + pixel-sized font (our QSS uses px font-size, so pointSize() is -1 by + design) — cosmetic console noise only, doesn't affect rendering. + Everything else still prints normally.""" + if "QFont::setPointSize" in message: + return + if msg_type == QtMsgType.QtWarningMsg: + print(f"Warning: {message}", file=sys.stderr) + elif msg_type == QtMsgType.QtCriticalMsg: + print(f"Critical: {message}", file=sys.stderr) + elif msg_type == QtMsgType.QtFatalMsg: + print(f"Fatal: {message}", file=sys.stderr) + else: + print(message, file=sys.stderr) + + def main(): + qInstallMessageHandler(_qt_message_handler) app = QApplication(sys.argv) app.setApplicationName("LabUI") diff --git a/ui/config_dialog.py b/ui/config_dialog.py index 5a95821..cefee2d 100644 --- a/ui/config_dialog.py +++ b/ui/config_dialog.py @@ -45,6 +45,7 @@ class DeviceConfigDialog(QDialog): btn_row = QHBoxLayout() btn_row.addStretch() close_btn = QPushButton("Close") + close_btn.setToolTip("Close this dialog — use Apply & Reconnect on the Hardware tab first if you changed backend settings") close_btn.setDefault(True) close_btn.clicked.connect(self.accept) btn_row.addWidget(close_btn) diff --git a/ui/control_editor.py b/ui/control_editor.py index d167517..624e4c1 100644 --- a/ui/control_editor.py +++ b/ui/control_editor.py @@ -274,6 +274,7 @@ class ControlEditorDialog(QDialog): self._script_status = QLabel("") self._script_status.setObjectName("traceSource") check_btn = QPushButton("Check Syntax") + check_btn.setToolTip("Compile the script above and report any syntax error, without running it") check_btn.clicked.connect(self._check_script) btn_row = QHBoxLayout() btn_row.addWidget(self._script_status, 1) @@ -287,8 +288,10 @@ class ControlEditorDialog(QDialog): div.setObjectName("devWindowDivider"); root.addWidget(div) btn_row = QHBoxLayout(); btn_row.addStretch() - cancel = QPushButton("Cancel"); cancel.clicked.connect(self.reject) + cancel = QPushButton("Cancel"); cancel.setToolTip("Discard changes and close") + cancel.clicked.connect(self.reject) ok = QPushButton("Create Control") + ok.setToolTip("Save this control widget to the Control Panel") ok.setObjectName("applyButton"); ok.setDefault(True) ok.clicked.connect(self._on_ok) btn_row.addWidget(cancel); btn_row.addWidget(ok) diff --git a/ui/control_panel.py b/ui/control_panel.py index adf48e6..f0e18ef 100644 --- a/ui/control_panel.py +++ b/ui/control_panel.py @@ -252,6 +252,7 @@ class OnOffSwitch(ControlWidget): # Big toggle button self._btn = QPushButton("OFF") + self._btn.setToolTip("Toggle this output on/off") self._btn.setObjectName("switchBtn") self._btn.setCheckable(True) self._btn.setMinimumHeight(52) @@ -338,12 +339,14 @@ class MotorControl(ControlWidget): btn_row = QHBoxLayout() self._dir_btn = QPushButton("▶ FWD") + self._dir_btn.setToolTip("Toggle motor direction (forward/reverse)") self._dir_btn.setObjectName("motorDirBtn") self._dir_btn.setCheckable(True) self._dir_btn.toggled.connect(self._on_dir) btn_row.addWidget(self._dir_btn) self._run_btn = QPushButton("START") + self._run_btn.setToolTip("Start/stop the motor at the speed set by the slider above") self._run_btn.setObjectName("motorRunBtnOff") self._run_btn.setCheckable(True) self._run_btn.toggled.connect(self._on_run) @@ -410,6 +413,7 @@ class SetpointControl(ControlWidget): sp_lbl.setFixedWidth(24) self._minus_btn = QPushButton("−") + self._minus_btn.setToolTip(f"Decrease setpoint by {self.step} {self.unit}") self._minus_btn.setObjectName("spStepBtn") self._minus_btn.setFixedWidth(32) self._minus_btn.clicked.connect(self._decrement) @@ -422,6 +426,7 @@ class SetpointControl(ControlWidget): self._sp_spin.valueChanged.connect(self._on_sp_changed) self._plus_btn = QPushButton("+") + self._plus_btn.setToolTip(f"Increase setpoint by {self.step} {self.unit}") self._plus_btn.setObjectName("spStepBtn") self._plus_btn.setFixedWidth(32) self._plus_btn.clicked.connect(self._increment) diff --git a/ui/main_window.py b/ui/main_window.py index 77f8286..19d4c69 100644 --- a/ui/main_window.py +++ b/ui/main_window.py @@ -188,6 +188,7 @@ class MainWindow(QMainWindow): # ── ⊞ View menu ─────────────────────────────────────────────────── view_btn = QPushButton("⊞ View ▾"); view_btn.setObjectName("toolbarSectionBtn") + view_btn.setToolTip("Show/hide the Control Panel and Namespace docks") self._view_menu = QMenu(self) self._act_ctrl_panel = QAction("Control Panel", self) @@ -209,16 +210,19 @@ class MainWindow(QMainWindow): tb.addWidget(view_btn) config_btn = QPushButton("⚙ Configure"); config_btn.setObjectName("toolbarSectionBtn") + config_btn.setToolTip("Open Configuration — Devices, Channels, and Plot layout") config_btn.clicked.connect(lambda: self._open_config(0)) tb.addWidget(config_btn) tb.addWidget(_sep()) self._run_btn = QPushButton("▶ RUN") + self._run_btn.setToolTip("Start/stop acquisition") self._run_btn.setObjectName("runButton"); self._run_btn.setCheckable(True) self._run_btn.clicked.connect(self._toggle_run); tb.addWidget(self._run_btn) self._log_btn = QPushButton("⬤ LOG") + self._log_btn.setToolTip("Start/stop logging data to CSV (only available while running)") self._log_btn.setObjectName("logButton"); self._log_btn.setCheckable(True) self._log_btn.setEnabled(False); self._log_btn.clicked.connect(self._toggle_log) tb.addWidget(self._log_btn) @@ -246,6 +250,7 @@ class MainWindow(QMainWindow): tb.addWidget(_sep()) set_btn = QPushButton("⚙ Settings") + set_btn.setToolTip("App settings, theme, plugins") set_btn.setObjectName("toolbarSectionBtn"); set_btn.setCheckable(True) set_btn.clicked.connect(lambda c: self._open_settings()) tb.addWidget(set_btn); self._btn_settings = set_btn diff --git a/ui/namespace_panel.py b/ui/namespace_panel.py index 2fcc7a1..7d8c42d 100644 --- a/ui/namespace_panel.py +++ b/ui/namespace_panel.py @@ -64,8 +64,7 @@ class NamespacePanel(QWidget): lay.setSpacing(0) hint = QLabel( - "Double-click a row to copy a ready-to-paste reference " - "(vars.get(...) or channels.get(...)) to the clipboard." + "Double-click a row to copy reference to clipboard" ) hint.setObjectName("traceSource") hint.setWordWrap(True) -- cgit v1.2.3