Qt官方示例:Fridge Magnets Example(冰箱贴)

news/2024/11/23 23:06:29/

冰箱贴类:

#include "draglabel.h"
#include <QtWidgets>DragLabel::DragLabel(const QString &text, QWidget *parent): QLabel(parent)
{QFontMetrics metric(font());QSize size = metric.size(Qt::TextSingleLine, text);QImage image(size.width() + 12, size.height() + 12, QImage::Format_ARGB32_Premultiplied);image.fill(qRgba(0, 0, 0, 0));QLinearGradient gradient(0, 0, 0, image.height()-1);gradient.setColorAt(0.0, Qt::white);gradient.setColorAt(0.2, QColor(200, 200, 255));gradient.setColorAt(0.8, QColor(200, 200, 255));gradient.setColorAt(1.0, QColor(127, 127, 200));QPainter painter(&image);painter.setRenderHint(QPainter::Antialiasing);painter.setBrush(gradient);painter.drawRoundedRect(QRectF(0.5, 0.5, image.width()-1, image.height()-1),25, 25, Qt::RelativeSize);painter.setFont(font());painter.setBrush(Qt::black);painter.drawText(QRect(QPoint(6, 6), size), Qt::AlignCenter, text);setPixmap(QPixmap::fromImage(image));m_labelText = text;
}QString DragLabel::labelText() const
{return m_labelText;
}

一个自定义的 QLabel,根据创建时传入的文本设确定一个图片的尺寸,使用渐变的画刷在图片绘制一个圆角矩形和文本,然后设置标签显示此图片。

然后是一个白色的窗口:

DragWidget::DragWidget(QWidget *parent): QWidget(parent)
{QFile dictionaryFile(QStringLiteral(":/dictionary/words.txt"));dictionaryFile.open(QFile::ReadOnly);QTextStream inputStream(&dictionaryFile);int x = 5;int y = 5;while (!inputStream.atEnd()){QString word;inputStream >> word;if (!word.isEmpty()){DragLabel *wordLabel = new DragLabel(word, this);wordLabel->move(x, y);wordLabel->show();wordLabel->setAttribute(Qt::WA_DeleteOnClose);x += wordLabel->width() + 2;if (x >= 245){x = 5;y += wordLabel->height() + 2;}}}QPalette newPalette = palette();newPalette.setColor(QPalette::Window, Qt::white);setPalette(newPalette);setMinimumSize(400, qMax(200, y));setWindowTitle(tr("Fridge Magnets"));setAcceptDrops(true);
}

从一个文本文件中读取内容:

每次读取一行,读取一行就创建一个冰箱贴并移动到相应的位置。最后设置窗口支持拖放。

鼠标按下的操作:

void DragWidget::mousePressEvent(QMouseEvent *event)
{DragLabel *child = static_cast<DragLabel*>(childAt(event->position().toPoint()));if (!child)return;QPoint hotSpot = event->position().toPoint() - child->pos();//鼠标按在child上的位置QByteArray itemData;QDataStream dataStream(&itemData, QIODevice::WriteOnly);dataStream << child->labelText() << QPoint(hotSpot);QMimeData *mimeData = new QMimeData;mimeData->setData(fridgetMagnetsMimeType(), itemData);mimeData->setText(child->labelText());QDrag *drag = new QDrag(this);drag->setMimeData(mimeData);drag->setPixmap(child->pixmap());drag->setHotSpot(hotSpot);child->hide();if (drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::CopyAction) == Qt::MoveAction)child->close();elsechild->show();
}

这里定义了一种自定义MIME类型:

static inline QString fridgetMagnetsMimeType() { return QStringLiteral("application/x-fridgemagnet"); }

内联的非成员函数,这种写法值得学习。

其中包含了了冰箱贴的文本和鼠标按下的位置。

开始拖放操作后,如果是拖放移到那么冰箱贴就隐藏了,拖动过程中显示的只是 QDrag::pixmap()。

拖动进入事件和拖动移到事件:

void DragWidget::dragEnterEvent(QDragEnterEvent *event)
{if (event->mimeData()->hasFormat(fridgetMagnetsMimeType())){if (children().contains(event->source())){event->setDropAction(Qt::MoveAction);event->accept();}else{event->acceptProposedAction();}}else if (event->mimeData()->hasText()){event->acceptProposedAction();}else{event->ignore();}
}void DragWidget::dragMoveEvent(QDragMoveEvent *event)
{if (event->mimeData()->hasFormat(fridgetMagnetsMimeType())){if (children().contains(event->source())){event->setDropAction(Qt::MoveAction);event->accept();}else{event->acceptProposedAction();}}else if (event->mimeData()->hasText()){event->acceptProposedAction();}else{event->ignore();}
}

这两个没啥好说的,主要是拖动放下事件:

void DragWidget::dropEvent(QDropEvent *event)
{if (event->mimeData()->hasFormat(fridgetMagnetsMimeType())){const QMimeData *mime = event->mimeData();QByteArray itemData = mime->data(fridgetMagnetsMimeType());QDataStream dataStream(&itemData, QIODevice::ReadOnly);QString text;QPoint offset;dataStream >> text >> offset;DragLabel *newLabel = new DragLabel(text, this);newLabel->move(event->position().toPoint() - offset);newLabel->show();newLabel->setAttribute(Qt::WA_DeleteOnClose);if (event->source() == this){event->setDropAction(Qt::MoveAction);event->accept();}else{event->acceptProposedAction();}}else if (event->mimeData()->hasText()){QStringList pieces = event->mimeData()->text().split(QRegularExpression(QStringLiteral("\\s+")), Qt::SkipEmptyParts);QPoint position = event->position().toPoint();for (const QString &piece : pieces){DragLabel *newLabel = new DragLabel(piece, this);newLabel->move(position);newLabel->show();newLabel->setAttribute(Qt::WA_DeleteOnClose);position += QPoint(newLabel->width(), 0);}event->acceptProposedAction();}else{event->ignore();}
}

第一个分支在拖动放下的位置新建冰箱贴,从 QMimeData 取出数据设置其文本和位置。

第二个分支指示拖动能用空白符分割的文本到当前窗口,则使用其文本创建冰箱贴。

涉及到的类:

  • QFontMetrics 
  • QLabel 
  • QFile 
  • QTextStream 
  • QMimeData 
  • QDataStream
  • QDrag

http://www.ppmy.cn/news/583710.html

相关文章

2.3 案例3 加点料-增加一张图片

本案例对应的源代码目录&#xff1a;src/chapter02/ks02_03。程序运行效果见图2-21。 图2-21 案例3运行效果 既然要进行界面编程&#xff0c;自然离不开图片。如果认为在按钮上使用文字太枯燥了&#xff0c;那么使用图标是不是会更好呢&#xff1f;本节讨论一下如何在Qt项目中…

微信缓存dat怎么转图片_PC微信dat如何转图片?方式方法

微信dat转码软件使用操作说明在线解码,各位同学下载软件后&#xff0c;如何操作?如何找到dat文件?如何使用?又有哪些注意事项呢?这里会为大家一一道来。问题1 &#xff1a;如果下载失败怎么办?请先检查网络&#xff0c;软件并没有放在我的网站上&#xff0c;而是放在大厂七…

html5无法处理像素点导致图片花了,教你使用Canvas处理图片的方法

Canvas&#xff0c;中文译为“画布”&#xff0c;HTML5中新增了元素&#xff0c;可以结合JavaScript动态地在画布中绘制图形。 今天&#xff0c;我们不讲Canvas的图形绘制&#xff0c;而是讲如何对图片进行处理。 大概流程非常简单&#xff0c;主要分为以下三个步骤&#xff1a…

计算机教室英语手抄报图片,英语手抄报图片四年级

英语手抄报图片四年级 四年级的小朋友们&#xff0c;下面是有关四年级上册英语单词表图片手抄报内容知识&#xff0c;欢迎大家阅读与了解。 小学四年级上册英语单词表&#xff1a;Unit 1 My Classroom window 窗户  board 写字板  light 灯;管灯  picture 画;图画 door 门…

Java大象进冰箱线程_把大象装进冰箱:HTTP传输大文件的方法

上次我们谈到了HTTP报文里的div&#xff0c;知道了HTTP可以传输很多种类的数据&#xff0c;不仅是文本&#xff0c;也能传输图片&#xff0c;音频和视频。 早期互联网上传输的基本上都是只有几k大小的文本和小图片&#xff0c;现在的情况则大有不同。网页里包含的信息实在太多了…

微信小程序上传图片到html,微信小程序-上传图片

在做小冰箱这个项目时&#xff0c;对物品的图片需要有一个上传功能。今天在这里讲一下这个功能是如何实现的。 首先讲述一下这个功能的完整描述&#xff1a;有一个上传图片的按钮&#xff0c;点击按钮&#xff0c;弹出操作菜单&#xff1a;从手机相册选择&#xff0c;拍照。点击…

java html转图片格式_java把html转成图片的方法

代码 1.1 html模版 static String HtmlTemplateStr = " "body {background-color: yellow}"+ "h1 {background-color: #00ff00}"+ "h2 {background-color: transparent}"+ "p {background-color: rgb(250,0,255)}"+ "p.no2 …

java canvas 打开图片_一步步教你利用Canvas对图片进行处理

前言 Canvas,中文译为“画布”,HTML5中新增了元素,可以结合JavaScript动态地在画布中绘制图形。 今天,我们不讲Canvas的图形绘制,而是讲如何对图片进行处理,话不多说了,来一起看看详细的介绍吧。 大概流程非常简单,主要分为以下三个步骤: Canvas图片处理 是的,就像把…