1、概述
源码放在文章末尾

该项目实现了可以移动的多边形窗口,项目demo演示如下所示:
《QT实用小工具·四十六》多边形窗口-LMLPHP
项目部分代码如下所示:

#include "polygonwindow.h"

#include <QBitmap>
#include <QQuickItem>
#include <QQmlFile>
#include <QSGSimpleTextureNode>

class PolygonItem : public QQuickItem
{
public:
    PolygonItem(QQuickItem *parent = nullptr) : QQuickItem (parent) {
        setFlag(ItemHasContents);
    }

    void setTexture(QSGTexture *texture);

protected:
    virtual QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *);

private:
    QScopedPointer<QSGTexture> m_texture;
};

void PolygonItem::setTexture(QSGTexture *texture)
{
    m_texture.reset(texture);
}

QSGNode* PolygonItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
{
    QSGSimpleTextureNode *n = static_cast<QSGSimpleTextureNode *>(node);
    if (n) {
        if (!m_texture.isNull()) {
            n->setTexture(m_texture.data());
            n->setFiltering(QSGTexture::Linear);
            n->setRect(boundingRect());
        }
    } else {
        n = new QSGSimpleTextureNode();
        if (!m_texture.isNull()) {
            n->setTexture(m_texture.data());
            n->setFiltering(QSGTexture::Linear);
            n->setRect(boundingRect());
        }
    }

    return n;
}

class PolygonWindowPrivate
{
public:
    QPoint m_startPos;
    QPoint m_oldPos;
    QUrl m_source;
    QPixmap m_background;
    QScopedPointer<PolygonItem> m_centerItem;
};

PolygonWindow::PolygonWindow(QWindow *parent)
    : QQuickWindow (parent)
{
    d = new PolygonWindowPrivate;
    setOpacity(0.8);
    setColor(Qt::transparent);
    setFlags(flags() | Qt::Window | Qt::FramelessWindowHint);

    connect(this, &QQuickWindow::widthChanged, this, [this](int) {
        changeTexture();
    });
    connect(this, &QQuickWindow::heightChanged, this, [this](int) {
        changeTexture();
    });
    connect(this, &QQuickWindow::sceneGraphInitialized, this, [this]() {
        d->m_centerItem.reset(new PolygonItem(contentItem()));
        changeTexture();
    });
}

PolygonWindow::~PolygonWindow()
{
    delete d;
}

QUrl PolygonWindow::source() const
{
    return d->m_source;
}

void PolygonWindow::setSource(const QUrl &source)
{
    if (source != d->m_source) {
        d->m_source = source;
        d->m_background = QQmlFile::urlToLocalFileOrQrc(source);
        changeTexture();
        emit sourceChanged();
    }
}

void PolygonWindow::mousePressEvent(QMouseEvent *event)
{
    d->m_startPos = event->globalPos();
    d->m_oldPos = position();
    event->ignore();

    QQuickWindow::mousePressEvent(event);
}

void PolygonWindow::mouseReleaseEvent(QMouseEvent *event)
{
    d->m_oldPos = position();

    QQuickWindow::mouseReleaseEvent(event);
}

void PolygonWindow::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        setPosition(d->m_oldPos - d->m_startPos + event->globalPos());
    }

    QQuickWindow::mouseMoveEvent(event);
}

void PolygonWindow::changeTexture()
{
    auto texture = d->m_background.scaled(size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    if (!texture.isNull()) {
        d->m_background = texture;
        setMask(QRegion(d->m_background.mask()));
        if (d->m_centerItem) {
            d->m_centerItem->setSize(size());
            d->m_centerItem->setTexture(createTextureFromImage(d->m_background.toImage(), TextureHasAlphaChannel));
        }
    }
    update();
}

源码下载

04-29 08:38