调试初版
This commit is contained in:
+55
-17
@@ -5,6 +5,7 @@
|
||||
#include <QPushButton>
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
|
||||
// 启动 500ms 闪烁:每 500ms 切换一次动态属性,QSS 据此在 40%↔100% 透明度间切换
|
||||
@@ -49,29 +50,67 @@ QString cancelButtonStyle(int fontPx)
|
||||
.arg(fontPx).arg(C::DANGER);
|
||||
}
|
||||
|
||||
// ===================== 按钮焦点光圈 =====================
|
||||
// ===================== 按钮焦点(选中)光圈 =====================
|
||||
ButtonFocusGlow::ButtonFocusGlow(const QColor& glow, QObject* parent)
|
||||
: QObject(parent), m_glow(glow)
|
||||
{
|
||||
}
|
||||
|
||||
// 触摸屏上手指抬起后指针并不会跟着移开,Qt 会把刚点过的按钮一直留在悬停(:hover)态。
|
||||
// 本项目的悬停样式与选中样式是同一套(蓝底/亮边),残留的悬停看起来就是"还选中着",
|
||||
// 此时再按 Tab 选中另一个按钮,屏幕上就出现了两个"选中"。选中态一律以焦点为准,
|
||||
// 故每次产生新的选中(点击/触摸按下、焦点移入)时,把其它按钮残留的悬停态清掉。
|
||||
static void clearStaleHover(QWidget* keep)
|
||||
{
|
||||
// 用 allWidgets 而非 qApp->findChildren:顶层窗口并非 QApplication 的子对象
|
||||
const QWidgetList all = QApplication::allWidgets();
|
||||
for (QWidget* w : all) {
|
||||
if (w == keep || !w->underMouse() || !qobject_cast<QAbstractButton*>(w))
|
||||
continue;
|
||||
w->setAttribute(Qt::WA_UnderMouse, false);
|
||||
w->update();
|
||||
}
|
||||
}
|
||||
|
||||
bool ButtonFocusGlow::eventFilter(QObject* obj, QEvent* ev)
|
||||
{
|
||||
if (ev->type() == QEvent::FocusIn || ev->type() == QEvent::FocusOut) {
|
||||
QWidget* w = qobject_cast<QWidget*>(obj);
|
||||
if (w && qobject_cast<QPushButton*>(w)) {
|
||||
if (ev->type() == QEvent::FocusIn) {
|
||||
if (!w->graphicsEffect()) { // 挂一圈发光(偏移 0 → 四周光晕)
|
||||
QGraphicsDropShadowEffect* g = new QGraphicsDropShadowEffect(w);
|
||||
g->setBlurRadius(40); // 光晕大小(越大越强)
|
||||
g->setOffset(0, 0);
|
||||
g->setColor(m_glow);
|
||||
w->setGraphicsEffect(g);
|
||||
}
|
||||
} else {
|
||||
w->setGraphicsEffect(nullptr); // Qt 会删除旧效果
|
||||
}
|
||||
QWidget* w = qobject_cast<QWidget*>(obj);
|
||||
if (!w)
|
||||
return QObject::eventFilter(obj, ev);
|
||||
|
||||
switch (ev->type()) {
|
||||
case QEvent::FocusIn:
|
||||
clearStaleHover(w); // 新的选中出现 → 旧按钮的悬停残影一并清掉
|
||||
if (qobject_cast<QPushButton*>(w) && !w->graphicsEffect()) {
|
||||
QGraphicsDropShadowEffect* g = new QGraphicsDropShadowEffect(w); // 挂一圈发光(偏移 0 → 四周光晕)
|
||||
g->setBlurRadius(40); // 光晕大小(越大越强)
|
||||
g->setOffset(0, 0);
|
||||
g->setColor(m_glow);
|
||||
w->setGraphicsEffect(g);
|
||||
}
|
||||
break;
|
||||
case QEvent::FocusOut:
|
||||
if (qobject_cast<QPushButton*>(w) && w->graphicsEffect()) {
|
||||
// 光晕带模糊、偏移为 0,会溢出按钮矩形画到父控件上。
|
||||
// 只重绘按钮自身清不掉溢出的那圈,Tab 移走焦点后仍会留下蓝色残影,
|
||||
// 所以把父控件整块标脏,连同按钮一起重绘。
|
||||
QWidget* parent = w->parentWidget();
|
||||
w->setGraphicsEffect(nullptr); // Qt 会删除旧效果
|
||||
w->update();
|
||||
if (parent)
|
||||
parent->update(parent->rect());
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonPress:
|
||||
// 触摸/点击与 Tab 归一到同一个焦点:谁最后操作,谁就是唯一的选中
|
||||
if (static_cast<QMouseEvent*>(ev)->button() == Qt::LeftButton
|
||||
&& (w->focusPolicy() & Qt::ClickFocus)) {
|
||||
w->setFocus(Qt::MouseFocusReason);
|
||||
clearStaleHover(w);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QObject::eventFilter(obj, ev);
|
||||
}
|
||||
@@ -95,8 +134,7 @@ bool ArrowKeyGuard::eventFilter(QObject* obj, QEvent* ev)
|
||||
QWidget* fw = QApplication::focusWidget();
|
||||
if (fw && qobject_cast<QAbstractButton*>(fw)) {
|
||||
const int k = static_cast<QKeyEvent*>(ev)->key();
|
||||
if (k == Qt::Key_Up || k == Qt::Key_Down
|
||||
|| k == Qt::Key_Left || k == Qt::Key_Right)
|
||||
if (Keys::up(k) || Keys::down(k))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-5
@@ -82,7 +82,7 @@ struct Telemetry {
|
||||
bool armHomed = false; // 是否已回位(用于底盘“机械臂未回位”告警)
|
||||
|
||||
// 洗消
|
||||
QString washMode = "--"; // 消除作业 / 消毒作业
|
||||
QString washMode = "--"; // 手动消除 / 手动消毒
|
||||
bool washStart = false; // 洗消启停反馈
|
||||
double flowA = 0.0; // A 药剂流量 L/min
|
||||
double flowB = 0.0; // B 药剂流量 L/min
|
||||
@@ -150,8 +150,22 @@ void stopBlink(QWidget* w, const char* prop = "blink");
|
||||
// 退出/取消按钮预设样式:被选中(悬停/按下/焦点)时红底白字
|
||||
QString cancelButtonStyle(int fontPx = 60);
|
||||
|
||||
// ===================== 按钮焦点光圈 =====================
|
||||
// 全局事件过滤器:任意 QPushButton 获得焦点时,在其四周加一圈发光(QSS 无法实现光晕)
|
||||
// ===================== 本机按键 =====================
|
||||
// 面板只提供 5 个键:Tab、Shift+Tab、空格、方向上、方向下。
|
||||
// 新增按键或调整键位只改这一处。
|
||||
namespace Keys {
|
||||
inline bool tab(int k) { return k == Qt::Key_Tab; }
|
||||
inline bool backtab(int k) { return k == Qt::Key_Backtab; } // Shift+Tab
|
||||
inline bool shifted(int mods) { return (mods & Qt::ShiftModifier) != 0; }
|
||||
inline bool space(int k) { return k == Qt::Key_Space; }
|
||||
inline bool up(int k) { return k == Qt::Key_Up; }
|
||||
inline bool down(int k) { return k == Qt::Key_Down; }
|
||||
}
|
||||
|
||||
// ===================== 按钮焦点(选中)光圈 =====================
|
||||
// 全局事件过滤器:任意 QPushButton 获得焦点时,在其四周加一圈发光;
|
||||
// 同时把"触摸/点击"与"Tab"归一到同一个焦点,并清除触摸残留在按钮上的悬停态,
|
||||
// 保证任意时刻只有一个按钮呈选中样式(新的操作覆盖原来的)。
|
||||
class ButtonFocusGlow : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -169,8 +183,7 @@ private:
|
||||
void installButtonFocusGlow(QApplication* app);
|
||||
|
||||
// ===================== 方向键(旋钮)隔离 =====================
|
||||
// 方向键在本机是"旋钮"键位,只由 ParamControl 用来调值。但 QAbstractButton 会把
|
||||
// 方向键当成沿焦点链换焦(等同 Tab/Shift+Tab),停在按钮上时按方向键焦点会乱跳。
|
||||
// 上/下方向键在本机是"旋钮"键位,只由 ParamControl 用来调值。
|
||||
// 这个全局过滤器把"焦点在按钮上时"的方向键吞掉,方向键只做调值、换焦只走 Tab。
|
||||
class ArrowKeyGuard : public QObject
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user