1、概述
源码放在文章末尾
该项目实现了可以移动的多边形窗口,项目demo演示如下所示:
项目部分代码如下所示:
#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();
}