需求:類似 Windows 任務欄的懸浮狀態欄,永遠置頂。但當彈出模態對話框時,標準置頂窗口會被模態對話框遮擋且無法操作。
// 在狀態欄窗口類中
#include
// 定時器或事件觸發調用
void StatusBar::keepOnTop() {
// HWND_TOPMOST: 置於所有非頂層窗口之前
// SWP_NOMOVE | SWP_NOSIZE: 不改變位置大小
// SWP_NOACTIVATE: 不激活窗口 (保持焦點在主應用)
SetWindowPos(
HWND_TOPMOST,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE
);
}
class FloatingStatusBar : public QDialog {
Q_OBJECT
public:
FloatingStatusBar(QWidget* parent = nullptr) : QDialog(parent) {
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
// 定時器確保持續置頂
QTimer* timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &FloatingStatusBar::forceTopMost);
timer->start(500); // 每 500ms 執行一次
}
protected:
void forceTopMost() {
#ifdef Q_OS_WIN
HWND hwnd = (HWND)winId();
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
#endif
}
// 防止關閉事件
void closeEvent(QCloseEvent* event) override { event->ignore(); }
};
SetWindowPos(HWND_TOPMOST, ...) 是核心 APISWP_NOACTIVATE 保證不搶奪焦點Qt::Tool 標誌隱藏任務欄圖標注意:此方案僅限 Windows 平台,跨平台需分別實現 (Linux 用 X11/Wayland API,macOS 用 NSWindowLevel)。