天天看點

Qt中實作懸浮視窗

前言

在做應用軟體的時候,經常會用到懸浮視窗。當把滑鼠指到某一個控件上時,自動出現一個懸浮視窗。本文就來講一下懸浮視窗如何實作。本文打算利用label控件和一個隻有textedit的widget實作這一功能。

具體描述就是,當把滑鼠移動到label上方時,隻有一個textEdit的widget會出現,當把滑鼠移開時,這個widget會隐藏。

label控件實作

首先,label控件自身沒有判斷滑鼠是否指向的功能,是以需要建立自己的label類,繼承自QLabel,然後重載enterEvent和leaveEvent(QEvent * event)函數。然後把label控件提升為這個自己的label類。

繼承自QLabel的label類h檔案實作:

#ifndef QMYLABEL_H
#define QMYLABEL_H

#include <QObject>
#include <QLabel>

class QMyLabel : public QLabel
{
    Q_OBJECT
public:
    explicit QMyLabel(QWidget *parent = nullptr);

signals:
    void show();
    void hide();

public slots:

private:
    void enterEvent(QEvent * event);
    void leaveEvent(QEvent * event);
};

#endif // QMYLABEL_H      

這裡大部分代碼都是qt自動生成的,除了滑鼠事件函數重載這個兩個函數和兩個信号。

繼承自QLabel的label類cpp檔案實作:

#include "qmylabel.h"

QMyLabel::QMyLabel(QWidget *parent)
{
    this->setMouseTracking(true);
}

void QMyLabel::enterEvent(QEvent * event)
{
    emit show();
}

void QMyLabel::leaveEvent(QEvent * event)
{
    emit hide();
}      

注意:

this->setMouseTracking(true);      

這句話一定要有,是用來開啟跟蹤滑鼠功能的。

還有必須要在滑鼠進入和離開事件中發送信号,這裡也可以改成一個信号但是有一個bool的參數分别代表顯示和隐藏。筆者也曾調試過用一個信号傳入不同參數的方式,但并沒有實作預期的功能,至今沒有找到原因。

懸浮視窗的實作

其次,建立一個qt帶界面的類,繼承自QWidget,界面中隻放一個textEdit,當然可以根據需要放任何控件。如果要自定義textEdit中顯示的内容,可以在構造函數中傳入textEdit内容作為參數。

floatpan.h實作:

#ifndef FLOATPAN_H
#define FLOATPAN_H

#include <QWidget>

namespace Ui {
class FloatPan;
}

class FloatPan : public QWidget
{
    Q_OBJECT

public:
    explicit FloatPan(QWidget *parent = 0,QString text = "default");
    ~FloatPan();

     void setCustomText(QString text);

private:

    Ui::FloatPan *ui;
};
#endif // FLOATPAN_H      

其中大部分内容是qt自動生成的,除了構造函數添加一個參數,添加一個設定自定義的内容的方法。

floatpan.cpp實作:

#include "floatpan.h"
#include "ui_floatpan.h"

FloatPan::FloatPan(QWidget *parent,QString text) :
    QWidget(parent),
    ui(new Ui::FloatPan)
{
    ui->setupUi(this);
    ui->textEdit->setText(text);
    QFont font;
    font.setPixelSize(20);
    font.setBold(true);
    ui->textEdit->setFont(font);
}

FloatPan::~FloatPan()
{
    delete ui;
}

void FloatPan::setCustomText(QString text)
{
    ui->textEdit->setText(text);
}      

在構造函數中設定字型和顯示的内容,并且實作設定自定義内容的方法。

如何使用

最後,在使用的地方,首先進行懸浮窗的設定

FloatPan *widget;
widget = new FloatPan(this);
widget->setCustomText(QString::fromLocal8Bit("測設\r\ntest\r\n測試"));      

然後在使用label控件的地方,進行信号和槽的連接配接

connect(ui->label_1,SIGNAL(show()),this,SLOT(showfloatwindow()));
connect(ui->label_1,SIGNAL(hide()),this,SLOT(hidefloatwindow()));      
void showfloatwindow()
{
    widget->setCustomText(QString::fromLocal8Bit("測設\r\ntest\r\n測試"));
    widget->show(); 
}
void hidefloatwindow()
{
    widget->hide(); 
}