In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article "how to use QGraphicsView to achieve bubble chat window + mine clearance" article of knowledge points are not understood by most people, so the editor gave you a summary of the following contents, detailed contents, clear steps, with a certain reference value, I hope you can finish reading this article, let's take a look at this "how to use QGraphicsView to achieve bubble chat window + mine clearance" article.
Final result:
There is a problem: text and cross-selection cannot be selected (but in theory, the effect of simulated selection can be achieved by rewriting mouse-related events)
The messages on the left and right are encapsulated Item, which in turn inherits from the same base class.
Bubble by rewriting void paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget); function, in which the position of the bubble is calculated and drawn according to the width and height of the text, and then the word is written on it.
And when the window size changes, you need to recalculate the text size and draw it.
# pragma once#include / / the base class of all item of chat element class ChatBaseItem: public QGraphicsRectItem {public: ChatBaseItem (); virtual ~ ChatBaseItem (); virtual int Resize (int width); / / input value is viewport wide, return value is item high}; # include "chatbaseitem.h" ChatBaseItem::ChatBaseItem (): QGraphicsRectItem () {} ChatBaseItem::~ChatBaseItem () int ChatBaseItem::Resize (int width) return 0
Left chat Bubble Item
# pragma once#include "chatbaseitem.h" # include class OtherMsgItem: public ChatBaseItem {public: OtherMsgItem (QPixmap icon, QString name, QString msg, QDateTime datetime = QDateTime ()); virtual ~ OtherMsgItem (); virtual int Resize (int width); / / return the height of the entire item protected: void paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget); virtual QRectF boundingRect () const;private: QGraphicsPixmapItem icon_item_; QGraphicsSimpleTextItem name_item_; QString text_; QSize text_size_ / / text size QDateTime datetime_;}; # include # include "othermsgitem.h" const int kMsgFontSize = 14 10 Const int kNameFontSize = 13 10 Const QPoint kNamePos = QPoint (64, 0); const QPoint kIconPos = QPoint (20, 8); const QPoint kBorderPos = QPoint (kNamePos.x (), kNamePos.y () + 18); const QMargins kMargins = QMargins (12 jigme 11, 12 Magi 11) / / distance of text from border const QPoint kTextPos = QPoint (kBorderPos.x () + kMargins.left (), kBorderPos.y () + kMargins.top ()); const int kMarginRight = 40; / / distance of frame from right side of window OtherMsgItem::OtherMsgItem (QPixmap icon, QString name, QString msg, QDateTime datetime / * = QDateTime () * /): ChatBaseItem (), datetime_ (datetime) {icon_item_.setPixmap (icon) Icon_item_.setPos (kIconPos); text_ = msg; QFont font ("Microsoft YaHei"); font.setPixelSize (kNameFontSize); name_item_.setText (name); name_item_.setPos (kNamePos); name_item_.setFont (font); name_item_.setBrush (QColor (153,153,153); icon_item_.setParentItem (this); name_item_.setParentItem (this) } OtherMsgItem::~OtherMsgItem () int OtherMsgItem::Resize (int width) / / the maximum width of text per line int row_width = width-kTextPos.x ()-kMarginRight-kMargins.right (); / / calculate the total width of text font.setPixelSize (kMsgFontSize); QFontMetrics font_matrics (font); int text_total_width = font_matrics.width (text_); int text_row_height = font_matrics.lineSpacing () If (row_widthsetPen (QColor (229,229,229), 1, Qt::SolidLine); painter- > drawRoundedRect (border.x (), border.y (), border.width (), border.height (), rnd.width (), rnd.height ()); / / Bubble painter- > setBrush (QBrush (Qt::white)); painter- > setPen (Qt::NoPen) Painter- > drawRoundedRect (border.x () + 1, border.y () + 1, border.width ()-2, border.height ()-2, rnd.width (), rnd.height ()); / / triangular, QRect rect1 (border.x () + 1, border.y () + 1,20,20); painter- > drawRect (rect1); / / Triangle QPen pen; pen.setColor (QColor (229,229,229)); painter- > setPen (pen) Painter- > drawLine (border.x (), border.y (), border.x () + 20, border.y ()); painter- > drawLine (border.x (), border.y (), border.x (), border.y () + 20); QPen penText; penText.setColor (QColor (51,51,51)); painter- > setPen (penText); QTextOption option1 (Qt::AlignLeft); option1.setWrapMode (QTextOption::WrapAtWordBoundaryOrAnywhere); painter- > setFont (font) QRectF text_rect (kTextPos.x (), kTextPos.y (), text_size_.width (), text_size_.height ()); painter- > drawText (text_rect, text_, option1); QRectF OtherMsgItem::boundingRect () const QRectF border (kBorderPos.x (), kBorderPos.y (), text_size_.width () + kMargins.left () + kMargins.right (), text_size_.height () + kMargins.top () + kMargins.bottom ()) Return QRectF (0penny 0border.width (), border.height ())
The right bubble is different from the left bubble, and when calculating the position, the left endpoint needs to be calculated based on the fact of the window width.
# pragma once#include "chatbaseitem.h" # include class SelfMsgItem: public ChatBaseItem {public: SelfMsgItem (QPixmap icon, QString msg, QDateTime datetime = QDateTime ()); virtual ~ SelfMsgItem (); virtual int Resize (int width); / / return the height of the entire item protected: void paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget); virtual QRectF boundingRect () const;private: QGraphicsPixmapItem icon_item_; QString text_; QSize text_size_ / / text size QDateTime datetime_; int port_width_;}; # include # include # include "selfmsgitem.h" const int kMsgFontSize = 14 per Const int kNameFontSize = 13 per Const int kIconY = 0 per Const int kBorderY = 10 per Const int kIconWidth = 34 per Const QMargins kIconMargins = QMargins; const QMargins kMargins = QMargins (12, 11, 12, 11); / / distance between the text and the border const int kMarginLeft = 40 / / the distance from the left side of the window SelfMsgItem::SelfMsgItem (QPixmap icon, QString msg, QDateTime datetime / * = QDateTime () * /): ChatBaseItem (), datetime_ (datetime), text_ (msg) {icon_item_.setPixmap (icon); icon_item_.setY (kIconY); icon_item_.setParentItem (this) } SelfMsgItem::~SelfMsgItem () {} int SelfMsgItem::Resize (int width) {port_width_ = width; / / maximum width of text per line int row_width = width-kMarginLeft-kMargins.left ()-kMargins.right ()-kIconWidth-kIconMargins.left ()-kIconMargins.right (); / / calculate the total width of text QFont font ("Microsoft YaHei"); font.setPixelSize (kMsgFontSize); QFontMetrics font_matrics (font) Int text_total_width = font_matrics.width (text_); int text_row_height = font_matrics.lineSpacing (); if (row_width
< text_total_width) { int row = text_total_width / row_width; int text_total_height = (row+1)* text_row_height; //row从零开始,需要补加1 text_size_.setWidth(row_width); text_size_.setHeight(text_total_height); } else { text_size_.setWidth(text_total_width); text_size_.setHeight(text_row_height); } return text_size_.height() + kMargins.top() + kMargins.bottom() + kBorderY;}void SelfMsgItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){ QSize rnd(17, 17); //气泡聊天框左端点需要根据控件宽度计算 QRectF border(port_width_- kIconMargins.left()-kIconMargins.right()-kIconWidth-text_size_.width()-kMargins.left()-kMargins.right() , kBorderY , text_size_.width() + kMargins.left() + kMargins.right() , text_size_.height() + kMargins.top() + kMargins.bottom()); icon_item_.setX(border.x()+ border.width() + 10); //气泡 painter->SetBrush (QBrush); painter- > setPen (Qt::NoPen); painter- > drawRoundedRect (border.x (), border.y (), border.width (), border.height (), rnd.width (), rnd.height ()); / / Triangle, QRect rect1 (border.x () + border.width ()-20, border.y (), 20,20); painter- > setPen (Qt::NoPen) Painter- > setBrush (QBrush (QColor (149,182,57)); painter- > drawRect (rect1); QPen penText; penText.setColor (QColor (255,255,255)); painter- > setPen (penText); QTextOption option1 (Qt::AlignLeft); option1.setWrapMode (QTextOption::WrapAtWordBoundaryOrAnywhere); QFont font ("Microsoft YaHei"); font.setPixelSize (kMsgFontSize); painter- > setFont (font) QRectF text_rect (border.x () + kMargins.left (), border.y () + kMargins.top (), text_size_.width (), text_size_.height ()); painter- > drawText (text_rect, text_, option1) } QRectF SelfMsgItem::boundingRect () const {QRectF border (port_width_-kIconMargins.left ()-kIconMargins.right ()-kIconWidth-text_size_.width ()-kMargins.left ()-kMargins.right (), kBorderY, text_size_.width () + kMargins.left () + kMargins.right (), text_size_.height () + kMargins.top () + kMargins.bottom () Return QRectF (0,0, border.width (), border.height ());}
The next step is to call view
# pragma once#include # include # include class ChatBaseItem;class ChatView: public QGraphicsView {Q_OBJECTpublic: ChatView (QWidget * parent); ~ ChatView (); void Resize (int width); void ClearAll (); void AppendSelfMessage (QPixmap icon,QString msg, QDateTime datetime); void AppendOtherMessage (QPixmap icon,QString name, QString msg, QDateTime datetime); protected: virtual void mousePressEvent (QMouseEvent * e); private: void CheckTime (QDateTime datetime) / / check whether the insertion time is required. The input value is the current message time void AppendTime (QDateTime datetime, QString time); QMap items_;}; # include # include "chatview.h" # include "chatbaseitem.h" # include "selfmsgitem.h" # include "othermsgitem.h" # include "chattimeitem.h" # include "src/vapplication.h" const int kMarkRole = Qt::UserRole;const int kRoleOtherMsg = kMarkRole + 1 chatview.h Const int kRoleSelfMsg = kRoleOtherMsg + 1 Const int kRoleTime = kRoleSelfMsg + 1 * parent): QGraphicsView (parent) {setScene (new QGraphicsScene ()); this- > setAlignment (Qt::AlignLeft | Qt::AlignTop); setStyleSheet ("background: rgb (245245245); border:0px"); this- > setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); this- > verticalScrollBar ()-> setStyleSheet (theStyleSheet ["scrollbar"]);} ChatView::~ChatView () {ClearAll () } void ChatView::Resize (int width) {int height = 20; for (ChatBaseItem* item: items_) {item- > setPos (0, height); height = height + item- > Resize (width); height + = 20;} this- > scene ()-> setSceneRect (QRectF (0,0, width, height);} void ChatView::ClearAll () {for (auto it = items_.begin (); it! = items_.end ()) ) {ChatBaseItem* item = it.value (); it = items_.erase (it); delete item;}} void ChatView::AppendSelfMessage (QPixmap icon, QString msg, QDateTime datetime) {ChatBaseItem* item = new SelfMsgItem (icon, msg, datetime) {ChatBaseItem* item > setData (kMarkRole,kRoleSelfMsg); CheckTime (datetime); scene ()-> addItem (item); items_.insert (datetime, item); Resize (this- > viewport ()-> width ()) Update (); / / Scroll to the bottom QScrollBar * vScrollBar = verticalScrollBar (); vScrollBar- > setValue (vScrollBar- > maximum ());} void ChatView::AppendOtherMessage (QPixmap icon, QString name, QString msg, QDateTime datetime) {ChatBaseItem* item = new OtherMsgItem (icon, name, msg, datetime); item- > setData (kMarkRole, kRoleOtherMsg); CheckTime (datetime); scene ()-> addItem (item); items_.insert (datetime, item); Resize (this- > viewport ()-> width ()) Update (); QScrollBar * vScrollBar = verticalScrollBar (); vScrollBar- > setValue (vScrollBar- > maximum ());} void ChatView::mousePressEvent (QMouseEvent * e) {/ / intercepted mouse click event} void ChatView::CheckTime (QDateTime datetime) {if (items_.size () = 0 | | datetime.secsTo (items_.lastKey ()) > 60 * 5pm 5 minutes * /) {/ / insert time before the first message QDateTime dt = datetime.addMSecs (- 1) AppendTime (dt,dt.toString ("hh:mm:ss"));} void ChatView::AppendTime (QDateTime datetime, QString time) {ChatBaseItem* item = new ChatTimeItem (time); item- > setData (kMarkRole, kRoleTime); scene ()-> addItem (item); items_.insert (datetime, item); Resize (this- > viewport ()-> width ()); update () # pragma once#include "chatbaseitem.h" # include class ChatTimeItem: public ChatBaseItem {public: ChatTimeItem (QString time); virtual ~ ChatTimeItem (); virtual int Resize (int width); protected: void paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget); private: QGraphicsSimpleTextItem text_item_; QString text_; int port_width_;} # include # include # include "chattimeitem.h" # include "color.h" ChatTimeItem::ChatTimeItem (QString time): ChatBaseItem () {text_item_.setText (time); item_tool::SetFontColor (& text_item_, 13, false, colorspace::GetTextLightColor ()); text_item_.setParentItem (this);} ChatTimeItem::~ChatTimeItem () int ChatTimeItem::Resize (int width) port_width_ = width; return text_item_.boundingRect (). Height () Void ChatTimeItem::paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) int width = text_item_.boundingRect () .width (); text_item_.setX ((port_width_-width) / 2)
When subclassing Item, be sure to override the virtual QRectF boundingRect () const; method to return the size of the actual item, let scene know, and add const, otherwise the paint cannot be triggered when the upper left corner of the message is out of the window.
The above is about "how to use QGraphicsView to achieve bubble chat window + demining function" of this article, I believe we all have a certain understanding, I hope the content shared by the editor will be helpful to you, if you want to know more related knowledge content, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.