PYQT/QT/Qtextedit

pyqt或QT在texredit控件中插入多个本地图片后,鼠标在某一图片点击后怎么获取该图片地址。
我的想法如下,但都失败了
1.重写鼠标点击事件,但是texredit里的图片没有鼠标点击事件,无法获取鼠标点击的是哪个图
2.让QTextImageFormat继承QWidget从而获得鼠标点击事件,但继承后无法上传照片

这是我的插入图片代码

    def insertRouteImage(self):
        #getImagePath为自己写的上传图片方法,path为return到的图片路径
        path = self.getImagePath()
        try
            tc = self.textEdit_2.textCursor()
            tif = QTextImageFormat()
            tif.setName(path)
            #获取插入图片的尺寸
            qpixmap = QtGui.QImage(path)
            width = qpixmap.width()
            height = qpixmap.height()

            # 设置图片宽度和高度
            scal = width/900
            scalHeight = height/scal
            tif.setWidth(900)
            tif.setHeight(scalHeight)
            tc.insertImage(tif)

如下图,需要通过鼠标单击或双击返回用户点击的是哪个图片

img

哪位熟悉QT的可以给出解决方案,感激不尽~

要实现鼠标点击texredit控件中的某个图片并获取该图片地址,你可以使用以下方法:

为每个插入的图片创建一个唯一的标识符,并将其与图片路径关联。例如,你可以将图片路径和一个唯一的整数ID存储在字典中。然后,重写QTextEdit的mousePressEvent方法以捕获鼠标点击事件。在这个方法中,获取鼠标点击位置的QTextCursor对象,然后调用QTextCursor的selectedText方法以获取当前选中的文本。如果选中的文本是一个插入的图片,则从字典中获取该图片的路径并进行后续处理。
下面是一个示例代码:

class MyTextEdit(QtWidgets.QTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.image_dict = {}

    def insertRouteImage(self):
        path = self.getImagePath()
        # 为每个图片创建唯一ID
        image_id = uuid.uuid4().hex
        self.image_dict[image_id] = path

        tc = self.textCursor()
        tif = QTextImageFormat()
        tif.setProperty('image_id', image_id)
        # 设置图片宽度和高度
        qpixmap = QtGui.QImage(path)
        width = qpixmap.width()
        height = qpixmap.height()
        scal = width/900
        scalHeight = height/scal
        tif.setWidth(900)
        tif.setHeight(scalHeight)
        tc.insertImage(tif)

    def mousePressEvent(self, event):
        # 捕获鼠标点击事件
        if event.button() == QtCore.Qt.LeftButton:
            pos = event.pos()
            cursor = self.cursorForPosition(pos)
            cursor.select(QTextCursor.WordUnderCursor)
            selected_text = cursor.selectedText()

            # 如果选中的文本是一个插入的图片,则获取其路径
            image_id = cursor.charFormat().property('image_id')
            if image_id:
                path = self.image_dict.get(image_id)
                if path:
                    print(f"Clicked on image: {path}")
                    return

        super().mousePressEvent(event)


在这个示例中,我们使用了Python的uuid模块来为每个插入的图片生成一个唯一的ID。我们还使用了QTextImageFormat的setProperty方法来将每个插入的图片与其ID关联。最后,在mousePressEvent方法中,我们检查当前选中的文本是否是一个插入的图片,并使用字典查找该图片的路径。如果找到了路径,则打印出来。

该回答引用ChatGPT

您可以考虑将每个插入的图片的路径信息保存在QTextImageFormat的userData中,在鼠标点击事件中获取当前点击位置的QTextCharFormat,判断其是否包含QTextImageFormat,并从中获取对应图片的路径信息。具体实现可以参考下面的代码示例:

class CustomTextEdit(QtWidgets.QTextEdit):
    def __init__(self, parent=None):
        super(CustomTextEdit, self).__init__(parent)
        self.imagePathDict = {}
        self.textChanged.connect(self.updateImagePathDict)

    def updateImagePathDict(self):
        # 更新图片路径字典
        tc = self.textCursor()
        for block in self.document().findBlocks():
            for fragment in block.fragments():
                charFormat = fragment.charFormat()
                if charFormat.isImageFormat():
                    imagePath = charFormat.toImageFormat().name()
                    if not imagePath in self.imagePathDict.values():
                        self.imagePathDict[id(imagePath)] = imagePath

    def mousePressEvent(self, event):
        super(CustomTextEdit, self).mousePressEvent(event)
        tc = self.textCursor()
        charFormat = tc.charFormat()
        if charFormat.isImageFormat():
            imagePath = charFormat.toImageFormat().name()
            if id(imagePath) in self.imagePathDict:
                # 获取对应图片路径信息
                imagePath = self.imagePathDict[id(imagePath)]
                print('Clicked image path:', imagePath)



在上面的示例中,每次文本内容改变时都会更新图片路径字典self.imagePathDict,其中字典的键值是对应图片路径的内存地址,这样可以保证不同的插入图片路径不会被误判为相同的图片。在鼠标点击事件中,首先判断当前鼠标位置的QTextCharFormat是否为QTextImageFormat,如果是则从imagePathDict中获取对应的图片路径信息。

在PyQt/Qt中,可以通过事件Event Filter来获取鼠标点击图片的事件。可以在插入图片时,为每个插入的图片设置一个事件过滤器,然后重写过滤器的事件处理函数来获取鼠标点击事件。
以下是一个示例代码,实现了在 QTextEdit 控件中插入图片,并在点击图片时获取图片的文件路径。

from PyQt5.QtWidgets import QApplication, QTextEdit
from PyQt5.QtGui import QTextImageFormat, QImage
from PyQt5.QtCore import QObject, pyqtSignal, QEvent, Qt


class ImageFilter(QObject):
    imageClicked = pyqtSignal(str)

    def eventFilter(self, obj, event):
        if event.type() == QEvent.MouseButtonPress:
            if event.button() == Qt.LeftButton:
                image_format = obj.currentImage()
                if image_format.isValid() and event.pos() in image_format.rect():
                    self.imageClicked.emit(image_format.name())
                    return True
        return QObject.eventFilter(self, obj, event)


class TextEdit(QTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.installEventFilter(ImageFilter(self))

    def insertImage(self, image_path):
        image_format = QTextImageFormat()
        image_format.setName(image_path)

        # 获取插入图片的尺寸
        qpixmap = QImage(image_path)
        width = qpixmap.width()
        height = qpixmap.height()

        # 设置图片宽度和高度
        scal = width/900
        scalHeight = height/scal
        image_format.setWidth(900)
        image_format.setHeight(scalHeight)

        self.textCursor().insertImage(image_format)

    def currentImage(self):
        cursor = self.textCursor()
        cursor.movePosition(cursor.Left, cursor.KeepAnchor)
        char_format = cursor.charFormat()
        return char_format.toImageFormat()


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    text_edit = TextEdit()
    text_edit.show()

    # 在 QTextEdit 中插入图片
    text_edit.insertImage('path/to/image1.jpg')
    text_edit.insertImage('path/to/image2.jpg')
    text_edit.insertImage('path/to/image3.jpg')

    # 在点击图片时获取图片的文件路径
    image_filter = text_edit.eventFilter
    image_filter.imageClicked.connect(lambda path: print(f'Clicked image: {path}'))

    sys.exit(app.exec_())

可以考虑使用QTextDocumentFragment类来获取图片地址。首先,在鼠标点击事件中获取QTextCursor,然后使用QTextCursor的selectionStart()和selectionEnd()方法获取QTextCursor的选择范围,再使用QTextDocumentFragment的fromText()方法获取QTextDocumentFragment,最后,通过QTextDocumentFragment的imageResources()方法获取图片地址。

你可以尝试使用QTextEdit的mousePressEvent()函数来获取鼠标点击的图片地址。具体来说就是可以使用QTextEdit的cursorForPosition()函数来获取鼠标点击的位置,然后使用QTextCursor的charFormat()函数来获取图片的地址。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

在QTextEdit中,每个插入的图片都会被转化为一个QTextImageFormat对象,可以通过QTextCursor.currentCharFormat()获取当前光标所在位置的QTextCharFormat对象,进而获得插入图片的QTextImageFormat对象。你可以在重写QTextEdit.mousePressEvent()方法时,获取光标所在位置的QTextImageFormat对象,然后从中获取图片路径。下面给出了一个如何获取图片路径的示例代码:

from PyQt5 import QtGui, QtWidgets
from PyQt5.QtGui import QTextCursor, QTextImageFormat
from PyQt5.QtCore import Qt

class MyTextEdit(QtWidgets.QTextEdit):
    def mousePressEvent(self, event):
        super().mousePressEvent(event)
        if event.button() == Qt.LeftButton:
            tc = self.textCursor()
            if not tc.hasSelection():
                # 获取光标所在位置的 QTextImageFormat 对象
                char_format = tc.currentCharFormat()
                if char_format.isImageFormat():
                    image_format = char_format.toImageFormat()
                    path = image_format.name()
                    print(path)

你可以通过在 QTextEdit 控件上重写 mousePressEvent 方法,并使用 cursorForPosition 方法获取光标位置,进而判断光标处是否有图片,如果有则获取该图片的路径。

以下是一个可能的实现:

import os
from PyQt5.QtWidgets import QTextEdit
from PyQt5.QtGui import QTextCursor


class MyTextEdit(QTextEdit):
    def __init__(self):
        super().__init__()
        self.image_paths = []

    def insertRouteImage(self):
        path = self.getImagePath()
        if path:
            tc = self.textCursor()
            tif = self.createImageFormat(path)
            tc.insertImage(tif)
            self.image_paths.append(path)

    def createImageFormat(self, path):
        tif = self.create_image_format()
        tif.setName(path)
        qpixmap = QtGui.QImage(path)
        width = qpixmap.width()
        height = qpixmap.height()
        scal = width / 900
        scalHeight = height / scal
        tif.setWidth(900)
        tif.setHeight(scalHeight)
        return tif

    def create_image_format(self):
        tif = QTextImageFormat()
        tif.setWidth(0)
        tif.setHeight(0)
        tif.setName("")
        return tif

    def mousePressEvent(self, event):
        super().mousePressEvent(event)
        pos = event.pos()
        cursor = self.cursorForPosition(pos)
        cursor.select(QTextCursor.WordUnderCursor)
        image_format = cursor.charFormat().toImageFormat()
        if not image_format.isNull():
            path = image_format.name()
            if path in self.image_paths:
                print(f"Selected image path: {os.path.abspath(path)}")

这里,我们重写了 QTextEdit 控件的 mousePressEvent 方法,用于捕捉鼠标点击事件。在方法中,我们首先调用了父类的 mousePressEvent 方法以确保控件可以正常响应鼠标事件。然后,我们通过 pos 参数获取鼠标点击的位置,使用 cursorForPosition 方法获取该位置对应的光标,并使用 select 方法选中光标所在位置的字符(此处假设一个图片作为一个字符)。然后,我们检查光标位置对应的字符是否为图片格式,如果是,则获取该图片的路径并打印出来。

在你的主程序中,你需要使用 MyTextEdit 控件代替原有的 QTextEdit 控件。例如:

from PyQt5.QtWidgets import QApplication, QMainWindow
import sys


class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.textEdit = MyTextEdit()
        self.setCentralWidget(self.textEdit)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

这里我们将自定义的 MyTextEdit 控件放在了主窗口中心,以替代原有的 QTextEdit 控件。
如果对您有帮助,请给与采纳,谢谢。

https://www.baidu.com/link?url=W51STh6LzGGuA8j3K6wQpo3WwAv5yy0L12gOHKjJ-H_yuOMUnKcHHsvJ-LgMTaz51c6xX0iZffMp0exOmJWBPHIDFDG2TyNUa5zbM75L31K&wd=&eqid=a2e72399000000b00000000263f2c023

导入Qt模块
from PyQt5.QtWidgets import QApplication, QTextEdit, QPushButton from PyQt5.QtGui import QPixmap

创建QApplication实例
app = QApplication([])

创建QTextEdit实例
textEdit = QTextEdit()

创建QPushButton实例
button = QPushButton('插入图片')

定义按钮点击事件
def on_click(): # 创建QPixmap实例 pixmap = QPixmap('图片路径') # 将图片插入到QTextEdit中 textEdit.insertHtml('' %!p(MISSING)ixmap.toImage())

绑定按钮点击事件
button.clicked.connect(on_click)

显示QTextEdit和QPushButton
textEdit.show() button.show()

运行QApplication
app.exec_()

以下答案基于ChatGPT与GISer Liu编写:

1.要实现鼠标点击图片后获取图片路径,可以通过重写 QTextEdit 的鼠标事件来实现。

2.在你的 QTextEdit 控件上设置一个自定义的鼠标事件处理函数,使用 QMouseEvent 中的 pos() 方法获取鼠标点击的位置,并使用 QTextCursor 中的 charFormat() 方法获取光标所在位置的文本格式,如果该格式为 QTextImageFormat,则获取该格式的名称(即路径)。

下面是一个示例代码,可以作为参考:

python

from PyQt5.QtWidgets import QTextEdit
from PyQt5.QtGui import QTextCursor, QTextImageFormat
from PyQt5.QtCore import Qt

class MyTextEdit(QTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setMouseTracking(True)
    
    def mousePressEvent(self, event):
        pos = event.pos()
        tc = self.cursorForPosition(pos)
        tc.select(QTextCursor.WordUnderCursor)
        fmt = tc.charFormat()
        if fmt.isImageFormat():
            img_fmt = QTextImageFormat(fmt)
            path = img_fmt.name()
            print("Clicked on image:", path)
        else:
            super().mousePressEvent(event)

在这个示例代码中,我们首先调用 cursorForPosition(pos) 方法获取鼠标点击位置的光标,然后调用 charFormat() 方法获取该光标位置的文本格式。如果该格式是一个图片格式,则获取该图片格式的路径,如果不是,则调用父类的 mousePressEvent 方法。

3.你可以将 MyTextEdit 控件用于你的项目中,替换原来的 QTextEdit 控件,并通过连接其 clicked 信号将用户点击事件与处理函数绑定。

为啥用text里面插图片呢,label不好吗,这个鼠标事件好写,单机双击,悬停,移动都可以发送信号