先简单描述一下我出现的问题,我是在写一个聊天界面,然后对于图片消息来说,一旦图片比较大时,滑动聊天界面就会出现了明显卡顿情况,原因是和我在写这个ImageMessage时直接在paintEvent中就进行了耗时的图片操作,也是我对于重绘事件的不够了解导致的
在c++ - Stabilize QWidget::paintEvent() calls frequency - Stack Overflow
QWidget Class | Qt Widgets | Qt 6.9.1中可以看到.大致告诉我们在paintEvent中不要进行一些其他的操作,他只负责绘制.
我这个MessageImage就是左下角这个长矩形,有点难度的地方在这个如何计算图片放置的位置,需要用到父元素来计算,我在解决卡顿时把updateUi从paintEvent直接提出来就出现了父元素为NULL,因为我使用MessageImage没有直接传父元素给构造函数,而是先创建在放入layout中,也就导致了更新ui时出现父元素为空的情况,然后我采用的是新增一个字段表示是否完成ui更新,updateUI将state设置为false__updateUi在父元素为空时会直接返回没有更新图片和state,然后让showEvent去再判断是否成功了,没成功再执行 一次 updateUi,这样就将原本卡顿的显示解决了.- class MessageImage : public QWidget {
- Q_OBJECT
- public:
- MessageImage(const QString& fileId,const QByteArray& content, bool isLeft);
- void updateUI(const QString& fileId, const QByteArray& content);
- protected:
- void paintEvent(QPaintEvent* event) override;
- void showEvent(QShowEvent* event) override;
- private:
- void __updateUi();
- private:
- QPushButton* image;
- QString fileId;
- QPixmap image_pixmap;
- bool isLeft;
- bool state; // 0 -- 未更新
- };
- //==========================================================================================
- MessageImage::MessageImage(const QString& fileId, const QByteArray& content, bool isLeft)
- :isLeft(isLeft),fileId(fileId),state(false)
- {
- this->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
- this->setStyleSheet("QPushButton{border:none;} QWidget{background-color:red}");
- image = new QPushButton(this);
- if (content.isEmpty()) {
- model::DataCenter* dataCenter = model::DataCenter::getInstance();
- connect(dataCenter, &model::DataCenter::getSingleFileDone, this,&MessageImage::updateUI,Qt::UniqueConnection);
- dataCenter->getSingleFileAsync(fileId);
- }
- else {
- updateUI(fileId, content);
- }
- }
- void MessageImage::updateUI(const QString& fileId, const QByteArray& content)
- {
- if (this->fileId.isEmpty() || content.isEmpty()) {
- return;
- }
- this->fileId = fileId;
- __scaledImageToWidth(content, image_pixmap);
- this->state = false;
- __updateUi();
- this->update();
- }
- void MessageImage::showEvent(QShowEvent* event)
- {
- QWidget::showEvent(event);
- if (!state) {
- __updateUi();
- }
- }
- void MessageImage::paintEvent(QPaintEvent* event)
- {
- Q_UNUSED(event);
- QWidget::paintEvent(event);
- }
- void __scaledImageToWidth(const QByteArray& body,__out QPixmap& pixmap) {
- pixmap.loadFromData(body);
- pixmap = pixmap.scaledToWidth(120, Qt::SmoothTransformation);
- }
- void MessageImage::__updateUi() {
- QObject* obj = this->parent();
- if (obj == nullptr || !obj->isWidgetType()) {
- return;
- }
- QWidget* parent = dynamic_cast<QWidget*> (obj);
- if (image_pixmap.isNull()) {
- image_pixmap.load(":/resource/images/xiaoju.jpg");
- }
- QRect r = image_pixmap.rect();
- qDebug() << "image rect " << r;
- parent->setMinimumHeight(r.height() + 30);
- image->setIconSize(QSize(r.width(), r.height()));
- image->setIcon(QIcon(image_pixmap));
- if (isLeft) {
- image->setGeometry(0, 0, r.width(), r.height());
- }
- else {
- image->setGeometry(parent->width() - r.width() - 65, 0, r.width(), r.height());
- }
- this->state = true;
- }
复制代码 来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |