Qt -QQ音乐歌词桌面

1.首先看一下效果 

 当鼠标移动到字体上时出现控制界面。接下来我们来详细的介绍如何实现的,在文档最后作者也会附上源代码让大家一起探讨。

 接上两篇的代码继续写:

QBasicTimer

简单的歌词效果(不能移动,无控件)

我们来看一下代码的改动如何:

在主窗口dialog.h文件中我们新增了eventFilter事件来使得桌面歌词可以移动。

#include <QDialog>
class WigglyWidget;
class subTitleWid;
class Dialog : public QDialog
{
    Q_OBJECT

protected:

    void paintEvent(QPaintEvent *event)override;

    void enterEvent(QEvent *event)override;
    void leaveEvent(QEvent *event)override;

    bool eventFilter(QObject *, QEvent *)override;
public:
    explicit Dialog(QWidget *parent = 0);

    subTitleWid * subTitlewid;
    WigglyWidget *wigglyWidget;

};

dialog.cpp

我们添加了setAutoFillBackground(false);如果启用,此属性将导致Qt在调用paint事件之前填充小部件的背景。所使用的颜色由小部件调色板中的QPalette::Window color角色定义。因为这个属性与qss设置有冲突。或者将这一行删除。

setAttribute(Qt::WA_TranslucentBackground, true);指示小部件应该具有半透明的背景窗口小部件将有一个alpha通道。设置这个标志会导致WA_NoSystemBackground被设置。在Windows上这个小部件还需要设置Qt::FramelessWindowHint窗口标志。这个标志由小部件的作者设置或清除。

同时重写eventFilter可以使得界面可以被拖动。


Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(700, 95);
    setWindowTitle(tr("MiMouse"));

    //setAutoFillBackground(false);
    setAttribute(Qt::WA_TranslucentBackground, true);
    setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);


    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->setContentsMargins(0,0,0,0);
    layout->setSpacing(0);

    wigglyWidget = new WigglyWidget;
    wigglyWidget->installEventFilter(this);


    subTitlewid = new subTitleWid;

    subTitlewid->installEventFilter(this);
    subTitlewid->hide();

    layout->addWidget(subTitlewid);
    layout->addWidget(wigglyWidget);

    QString strSubTitle = "测试字幕的效果";
    wigglyWidget->setText(strSubTitle);

}

void Dialog::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.fillRect(rect(),QColor(50,50,50,153));

    QWidget::paintEvent(event);
}

void Dialog::enterEvent(QEvent *event)
{
    Q_UNUSED(event);
    /*显示字幕的背景*/
    wigglyWidget->setMask(true);
    /*显示设置界面*/
    subTitlewid->show();

}

void Dialog::leaveEvent(QEvent *event)
{
    Q_UNUSED(event);
    /*隐藏字幕的背景*/
    wigglyWidget->setMask(false);
    /*隐藏设置界面*/
    subTitlewid->hide();
}

bool Dialog::eventFilter(QObject *obj, QEvent *evt)
{
    static QPoint mousePoint;
    static bool mousePressed = false;

    QMouseEvent *event = static_cast<QMouseEvent *>(evt);
    if (event->type() == QEvent::MouseButtonPress) {
        if (event->button() == Qt::LeftButton) {
            mousePressed = true;
            mousePoint = event->globalPos() - pos();
            return true;
        }
    } else if (event->type() == QEvent::MouseButtonRelease) {
        mousePressed = false;
        return true;
    } else if (event->type() == QEvent::MouseMove) {
        if (mousePressed && (event->buttons() && Qt::LeftButton)) {
            move(event->globalPos() - mousePoint);
            return true;
        }
    }
    return QObject::eventFilter(obj, evt);
}

因为父窗口在paintEvent中drawRect(rect())将整个窗口都重新绘制了透明区域。所以在标题设置栏就不用再次绘制了。

在子界面(歌词界面)中构造函数中添加 setAttribute(Qt::WA_TranslucentBackground,true);可以使得子窗口透明,在我们想要其显示的时候在在paintEvetn中绘制出界面即可。可能说的比较笼统,具体实现见下面的代码。

总结:

1.当顶层窗口设置  setAttribute(Qt::WA_TranslucentBackground, true);时,会使得背景透明但是控件不透明。这时可以在PainterEvent中用

 QPainter painter(this);
 painter.fillRect(rect(),QColor(50,50,50,153));

来绘制背景。

2.其子控件如果设置了

setAutoFillBackground(true);//该函数用于设置当窗口作为被包含窗口时, 是否需要绘制背景。注意:QT窗口系统默认状态下, 当一个窗口作为被包含窗口时, 其不再绘制背景, 即使指定了背景绘制参数(如背景颜色、背景图片等)。

这时会不受父控件的背景色影响,从而来绘制属于自己的背景。当然此时也可以来进行 setAttribute(Qt::WA_TranslucentBackground, true);使得自己也背景透明的操作等。

注:1.若不设置setAutoFillBackground(true);(默认false),则受到父窗口的影响。

2.用drawRect绘制背景时,记得设置Pen为Qt::NoPen;,不然会有边缘线

3.尽量不要让父窗口的qss影响子控件

源码

源代码

猜你喜欢

转载自blog.csdn.net/yonggandess/article/details/107321238