最近在学习开发聊天软件的过程中想要模仿一下微信拖动图片到文本输入框中显示并能够发送的逻辑。经过查阅资料发现可以通过重写Qt的QTextEdit中的dropevent事件来实现。dropevent事件代码如下:
void MyEdit::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasUrls())
{
auto urls = event->mimeData()->urls();
if (urls.size() > 0)
{
for (auto& url : urls)
{
QFileInfo info(url.toLocalFile());
if (QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1()))
{
QTextDocument * textDocument = this->document();
QImage image = QImageReader(url.toString()).read();
textDocument->addResource(QTextDocument::ImageResource, url, QVariant(image));
QTextCursor cursor = this->textCursor();
QTextImageFormat imageFormat;
imageFormat.setWidth(80);
imageFormat.setHeight(50);
imageFormat.setName(url.toString());
cursor.insertImage(imageFormat);
}
}
}
}
event->accept();
}
我们拖动图片释放之后会得到一个对应的文件url,如果拖动多个文件则会有多个url对于每个url我们进行相应的判断,如果是图片的话,则将其转换为图片,并通过textCursor()获取到鼠标当前所在的位置,进而将其插入到对应位置。需注意程序不能已管理员身份运行,否则会因windows限制导致程序无法捕获到drop事件。
实际效果如下所示图:
![](https://img-blog.csdnimg.cn/img_convert/d207345559ab0bee72e8516215a3a29d.png)
而想要从文本框中获取图片则可以使用一下代码。
其中QTextDocument是文本对象,通过其可以获取文本块(QTextBlock)。也可以获取到框架(QTextFrame)表格(QTextTable)列表(QTextList)等,但在本文这里无需获取上述内容。输入框中可能有多个文本块,回车或换行就会产生一个新的文本块,我们遍历文本块中的内容,如果遇到了图片,则可以通过下述方式获取其相关内容,其中的name就是图片路径,后续的网络发送或其他操作都可以通过这个路径进行。
void testTextImage::onSignalGet()
{
QTextDocument* document = ui.textEdit->document();
QTextBlock block = document->begin();
while (block.isValid())
{
for (auto iter = block.begin(); iter != block.end(); ++iter)
{
QTextCharFormat format = iter.fragment().charFormat();
bool isImage = format.isImageFormat();
if (isImage)
{
auto imageFormat = format.toImageFormat();
auto name = imageFormat.name();
auto type = document->resource(QTextDocument::ImageResource, imageFormat.name()).typeName();
}
}
block = block.next();
}
}