文章目录
- 1.说明
- 2.程序截图
- 3.TextBalloon 类
- 3.1 TextBalloon.h
- 3.2 TextBalloon.cpp
- 3.3 textballoons.qml
- 3.4 main.cpp
1.说明
QQuickPaintedItem类提供了一种在QML场景图中使用QPainter API的方法。
QQuickPaintedItem本身作为Item,也可以在ListView中作为代理使用。
案例本身是官方的例子,但是使用的方式是用qml的插件方式,先修改成普通的注册类型使用。插件以后再学习。
2.程序截图
程序运行界面如图:
3.TextBalloon 类
3.1 TextBalloon.h
#ifndef TEXTBALLOON_H
#define TEXTBALLOON_H#include <QQuickPaintedItem>
#include <QQuickItem>
#include <QtQml>class TextBalloon : public QQuickPaintedItem
{Q_OBJECTQ_PROPERTY(bool rightAligned READ isRightAligned WRITE setRightAligned NOTIFY rightAlignedChanged)
public:TextBalloon(QQuickItem *parent = 0);public:virtual void paint(QPainter *painter) override;bool isRightAligned() const;void setRightAligned(bool newRightAligned);const QColor &background() const;void setBackground(const QColor &newBackground);signals:// QQuickPaintedItem interfacevoid rightAlignedChanged();void backgroundChanged();private:bool m_rightAligned;QColor m_background;Q_PROPERTY(QColor background READ background WRITE setBackground NOTIFY backgroundChanged)
};#endif // TEXTBALLOON_H
3.2 TextBalloon.cpp
#include "TextBalloon.h"#include <QBrush>
#include <QPainter>TextBalloon::TextBalloon(QQuickItem *parent):QQuickPaintedItem(parent),m_rightAligned(false),m_background("steelblue")
{
}void TextBalloon::paint(QPainter *painter)
{painter->setBrush(m_background);painter->setPen(Qt::NoPen);painter->setRenderHint(QPainter::Antialiasing);QSizeF itemSize = size();painter->drawRoundedRect(0, 0, itemSize.width(), itemSize.height() - 10, 10, 10);if (m_rightAligned){const QPointF points[3] = {QPointF(itemSize.width() - 10.0, itemSize.height() - 10.0),QPointF(itemSize.width() - 20.0, itemSize.height()),QPointF(itemSize.width() - 30.0, itemSize.height() - 10.0),};painter->drawConvexPolygon(points, 3);}else{const QPointF points[3] = {QPointF(10.0, itemSize.height() - 10.0),QPointF(20.0, itemSize.height()),QPointF(30.0, itemSize.height() - 10.0),};painter->drawConvexPolygon(points, 3);}
}bool TextBalloon::isRightAligned() const
{return m_rightAligned;
}void TextBalloon::setRightAligned(bool newRightAligned)
{if (m_rightAligned == newRightAligned)return;m_rightAligned = newRightAligned;emit rightAlignedChanged();
}const QColor &TextBalloon::background() const
{return m_background;
}void TextBalloon::setBackground(const QColor &newBackground)
{if (m_background == newBackground)return;m_background = newBackground;emit backgroundChanged();
}
3.3 textballoons.qml
// textballoons.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQml.Models 2.15
import TextBalloon 1.0Item {height: 480width: 320// 消息显示栏ListView{id:listViewanchors.left: parent.leftanchors.right: parent.rightanchors.top: parent.topanchors.bottom: row.topspacing:10delegate: TextBalloon{x: rightAligned ? listView.width - width : 0width: msg.widthheight: msg.implicitHeight + 10rightAligned: index%2background: "#1e6eff"Label{padding: 10id: msgtext:messagecolor: "white"width: implicitWidth > listView.width ? listView.width : implicitWidthwrapMode: Label.Wrap}}model: ListModel{id:listModel}} // 消息显示栏 end// 发送栏Row{id:rowheight: 30spacing: 10anchors.left: parent.leftanchors.right: parent.rightanchors.bottom: parent.bottom// 消息输入框Rectangle{width: parent.width-50-parent.spacingheight: parent.heightborder.color: "black"TextEdit{id : edittext: "聊天内容xxxx"anchors.fill: parentverticalAlignment: Text.AlignVCenter}} // 消息输入框 endButton{width: 50height: parent.heighttext: "发送"property real index: 1onClicked: {index *= 10listModel.append({"message":edit.text+index});listView.positionViewAtEnd()}}} // 发送栏 end
}
3.4 main.cpp
#include <QApplication>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include "TextBalloon.h"int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);qmlRegisterType<TextBalloon>("TextBalloon",1,0,"TextBalloon");QQuickView view;view.setSource(QUrl(QStringLiteral("qrc:/painteditem/textballoons.qml")));view.show();return app.exec();
}