1. 程式人生 > >qt關於一些托盤,工作列圖示隱藏,無邊框等的一些視窗的效果

qt關於一些托盤,工作列圖示隱藏,無邊框等的一些視窗的效果

現在用到的挺多的軟體基本都需要實現到這些個的功能。

1.對於無邊框透明的視窗,其實兩個設定兩句話就搞定了

setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::FramelessWindowHint);

然後就是這樣之後無法響應滑鼠的拖動,所以你要過載時間處理函式來實現滑鼠的按下然後拖動的時間,其實就是根據滑鼠的移動事件,判斷如果按鍵是按下的狀態,那麼久move整個控制元件這樣子。當然你覺得如果好多個視窗都要實現這個功能或者說你覺的寫在程式的視窗類裡面去過載這些個函式不太好。那麼你可以自己建一個QOBJECT,然後利用這個object來處理視窗的事件。例如你的win視窗,需要實現這個功能,那麼你就呼叫

win->installEventFilter(this);this指的是你自己新建的用來處理拖動的時間的qobject類,然後多個win你都可以註冊到這個obj上,之後你註冊過的視窗的事件都會經過這個obj,你就可以在這裡:eventFilter(QObject* obj, QEvent* event) 拿到滑鼠的移動的資訊,還可以判斷拿到的物件,然後去實現想要的功能。其實用到的就是installEventFilter這個函式的事件註冊的效果而已,然後有一點比較重要的就是:installEventFilter註冊過的視窗,事件觸發時候的優先順序是越後註冊的優先順序越高,所以在後來註冊的類裡如果你在eventFilter裡做完處理return了一個true,那訊息就不會繼續走,後面(先前註冊的類)就拿不到這個訊息。

這個是要注意一下的,根據需求也能調整一下注冊的順序。對應的解除安裝就是removeEventFilter函式。

2.然後說一下托盤的事情

托盤其實利用的是QSystemTrayIcon這個類來實現。

    system_tray = new QSystemTrayIcon(this);
    system_tray->setToolTip("標題");
    system_tray->setIcon(QIcon(":/image/image/mhbox.ico"));
    TrayMenu *tray_menu = new TrayMenu(this);
    system_tray->setContextMenu(tray_menu);
    connect(ui->pushButton_close,&QPushButton::clicked,this,[=](){this->hide();});
    connect(tray_menu,&TrayMenu::appShow,this,[=](){this->showNormal();});
    connect(tray_menu,&TrayMenu::appInfo,this,[=](){});
    connect(tray_menu,&TrayMenu::appQuit,this,[=](){qApp->exit();});
    connect(system_tray,&QSystemTrayIcon::activated,this,[=](QSystemTrayIcon::ActivationReason reason){
        if(reason == QSystemTrayIcon::DoubleClick)
        {
            this->showNormal();
        }
    });
    system_tray->show();

這個應該比較簡單了,然後裡面的對應的TrayMenu就需要過載一下QMenu實現一下對應的QAction和signal就好了:
class TrayMenu : public QMenu
{
    Q_OBJECT
public:
    QAction* action_quit;
    QAction* action_about;
    QAction* action_restore;

    explicit TrayMenu(QWidget *parent = 0);

    void createAction();
signals:
    void appQuit();
    void appShow();
    void appInfo();

public slots:

};

TrayMenu::TrayMenu(QWidget *parent) :
    QMenu(parent)
{
    createAction();
}

void TrayMenu::createAction()
{
    action_quit = new QAction(this);
    action_quit->setIcon(QIcon(":/image/image/close.png"));
    action_quit->setText("退出");
    action_about = new QAction(this);
    action_about->setIcon(QIcon(":/image/image/info.png"));
    action_about->setText("關於");
    action_restore = new QAction(this);
    action_restore->setIcon(QIcon(":/image/image/home.png"));
    action_restore->setText("還原程式");
    this->addAction(action_restore);
    this->addAction(action_about);
    this->addSeparator();
    this->addAction(action_quit);
    //訊號
    connect(action_restore,&QAction::triggered,this,&TrayMenu::appShow);
    connect(action_about,&QAction::triggered,this,&TrayMenu::appInfo);
    connect(action_quit,&QAction::triggered,this,&TrayMenu::appQuit);
}
這樣就是實現的大概,具體的都是進一步來修改。

3.然後最後就是這個工作列圖示的問題。

工作列就是我們window下邊的現實開啟的程式的那個地方。可能你需要說不想要你的程式顯示在那裡,比如像qq這樣子的視窗,那麼其實你可以這樣設定:

setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint|Qt::Tool);

其實也就比之前多了一個這個Qt::WindowStaysOnTopHint|Qt::Tool,前一個是指定視窗的置頂,後一個就是實現隱藏的工作列圖示,但是如果是最小化的話,會出現一個懸浮的小視窗,解決就是如果有托盤,那麼點選最小化的時候你擷取事件然後觸發hide而不是最小化就好了。