我想创建一个文本编辑器,您可以在其中拖放Pyqtgraphs并与其进行实时交互。我在理解TextEdit的行为以及如何将小部件“嵌入” TextEdit本身时遇到了麻烦。在查看API之后,似乎只能将文本,html和图像添加到QTextEdit中。
我可能在这里抓住稻草,但我希望有void QTextEdit::insertWidget(QWidget*)
或类似性质的东西。
这里要澄清的是不完整的示例代码:
import sys
import numpy as np
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import pyqtgraph as pg
class PlotTextEditor(QMainWindow):
def __init__(self):
super().__init__()
self.textEdit = QTextEdit(self)
self.setCentralWidget(self.textEdit)
toolbar = QToolBar()
plotAction = QAction('Plot', self)
plotAction.triggered.connect(self.addPlot)
toolbar.addAction(plotAction)
self.addToolBar(toolbar)
self.setGeometry(300, 100, 800, 1000)
def addPlot(self):
x = np.linspace(0, 10, 100)
y = np.sin(x)
glWidget = pg.GraphicsLayoutWidget()
plot = glWidget.addPlot()
plot.plot(x, y, pen='r')
# I'd like to be able to use a line such as this
# self.textEdit.textCursor().insertWidget(glWidget)
self.textEdit.textCursor().insertText('I want to insert a widget pointer instead.')
if __name__ == "__main__":
app = QApplication(sys.argv)
pte = PlotTextEditor()
pte.show()
sys.exit(app.exec_())
我的一些想法是将pyqtgraph覆盖在空白图像上,或者尝试找到某种文本小部件,我可以插入并覆盖paintevent来为其提供pyqtgraph绘画。但最终,我不确定使用TextEdit在当前的Qt后端中是否还可以实现。
答案 0 :(得分:2)
请尝试使用此代码。
如果您想了解更多信息,请通过评论询问我。 我不知道你是否喜欢这个结果。
更新过渡
情节图像,但不渲染数据。
我将pen = 'r': plot.plot(x, y, pen)
更改为plot.plot(x, y, pen = 'r')
绘图图像的数据很脏,并且没有抗锯齿,会断断续续地被拦截。
我更新intrinsicSize()
并返回图片宽度和图片高度,
如果根据需要在return QSizeF()
中设置intrinsicSize
参数,则结果可能会很糟糕。
我们尽可能地互动。
如您所见,此图像由QPainter
绘制。因此,本来这是非交互的。我认为这是将结果呈现为QTextObject
的唯一方法。 QTextEdit
不能接受一种小部件作为文本。
请单击图像前面。
显示GraphicsLayoutWidget
。更改图形内容,然后将其关闭。下次,图像将重新绘制并再次渲染。
我删除了不必要的代码。
无论如何,我一直试图做到这一点。
请通过评论询问我进一步的消息。
import sys
import numpy as np
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import pyqtgraph as pg
import pyqtgraph.exporters
import os
plot_image_dict = {}
class PlotObjectInterface(QObject, QTextObjectInterface):
def __init__(self, parent=None):
super(PlotObjectInterface, self).__init__(parent=None)
def drawObject(self, painter, rect, doc, posInDocument, format):
img = format.property(1)
painter.save()
painter.setRenderHints(QPainter.Antialiasing)
painter.drawImage(QRectF(rect), img)
painter.restore()
def intrinsicSize(self, doc, posInDocument, format):
img = format.property(1)
width = img.size().width()
height = img.size().height()
return QSizeF(width, height)
class PlotTextEdit(QTextEdit):
def __init__(self):
super().__init__()
class PlotView(QGraphicsView):
def __init__(self):
super().__init__()
self.plot_scene = QGraphicsScene()
self.plot_tedit = PlotTextEdit()
self.plot_tedit.resize(800, 1000)
self.plot_scene.addWidget(self.plot_tedit)
self.setScene(self.plot_scene)
class PlotGraphicsLayoutWidget(pg.GraphicsLayoutWidget):
def __init__(self):
super().__init__()
self.current_edit_filename = ""
self.current_edit_imagenum = 0
self.current_edit_image = QImage()
self.current_edit_position = 0
def updateImage(self):
#overwrite the image
pg.QtGui.QApplication.processEvents()
exporter = pg.exporters.ImageExporter(self.scene())
filename = os.path.join(self.current_edit_filename)
exporter.export(filename)
image = QImage()
image.load(filename)
image_info = plot_image_dict[self.current_edit_imagenum]
tc = QTextCursor(self.current_text_edit.document())
tc.setPosition(image_info[3] - 1, tc.MoveAnchor)
tc.movePosition(tc.Right, tc.KeepAnchor, 1)
tc.setKeepPositionOnInsert(True)
char = QTextCharFormat()
char.setObjectType(QTextFormat.UserObject + 1)
char.setProperty(1, image)
char.setProperty(2, image_info[1])
char.setProperty(3, image_info[2])
char.setProperty(4, image_info[3])
plot_image_dict[self.current_edit_imagenum] = [image, image_info[1], image_info[2], image_info[3]]
tc.insertText("\ufffc", char)
tc.setKeepPositionOnInsert(False)
def closeEvent(self, event):
self.updateImage()
return pg.GraphicsLayoutWidget.closeEvent(self, event)
class PlotTextEditor(QMainWindow):
def __init__(self):
super().__init__()
self.plotview = PlotView()
self.pyplotObjectInterface = PlotObjectInterface()
self.plotview.plot_tedit.document().documentLayout().registerHandler(QTextFormat.UserObject+1,self.pyplotObjectInterface)
self.plotview.plot_tedit.viewport().installEventFilter(self)
self.setCentralWidget(self.plotview)
toolbar = QToolBar()
plotAction = QAction('Plot', self)
plotAction.triggered.connect(self.insertImage)
toolbar.addAction(plotAction)
self.addToolBar(toolbar)
self.setGeometry(300, 100, 800, 1000)
self.test_glWidget = PlotGraphicsLayoutWidget()
self.test_glWidget.current_text_edit = self.plotview.plot_tedit
self.test_manipulation = False
x = np.linspace(0, 10, 100)
y = np.sin(x)
plot = self.test_glWidget.addPlot()
#PlotDataItem
plot.plot(x, y, pen = 'b')
def closeEvent(self, event):
QApplication.closeAllWindows()
return QMainWindow.closeEvent(self, event)
def eventFilter(self, obj, event):
if event.type() == QMouseEvent.MouseButtonPress and obj == self.plotview.plot_tedit.viewport():
tc = self.plotview.plot_tedit.textCursor()
position = tc.position()
tc.movePosition(tc.Left, tc.KeepAnchor,1)
if tc.selectedText() == "\ufffc":
self.editImage(tc)
tc.clearSelection()
tc.setPosition(position)
p_next = position + 1
tc.setPosition(p_next, tc.KeepAnchor)
if tc.selectedText() == "\ufffc":
print("next character is \ufffc")
tc.clearSelection()
self.editImage(tc)
return False
return QMainWindow.eventFilter(self, obj, event)
def editImage(self, tc):
tc = QTextCursor(tc)
rect = self.plotview.plot_tedit.cursorRect(tc)
topLeft = rect.topLeft()
child_topLeft = self.plotview.mapToGlobal(topLeft)
char = tc.charFormat()
plot_img = char.property(1)
plot_num = char.property(2)
filename = char.property(3)
char.setProperty(4, tc.position())
if plot_img is not None:
geometry = QRect(topLeft,QSize(plot_img .width(), plot_img .height()))
self.test_glWidget.current_edit_filename = filename
self.test_glWidget.current_edit_imagenum = plot_num
self.test_glWidget.current_edit_image = plot_img
self.test_glWidget.current_edit_position = tc.position()
plot_image_dict[self.test_glWidget.current_edit_imagenum] = [plot_img, plot_num, filename, tc.position()]
self.test_glWidget.setGeometry(geometry)
self.test_glWidget.show()
def insertImage(self):
pg.QtGui.QApplication.processEvents()
exporter = pg.exporters.ImageExporter(self.test_glWidget.scene())
filename = os.path.join(os.getcwd(), "plot.png")
exporter.export(filename)
plot_img = QImage()
plot_img.load(filename)
plot_num = len(plot_image_dict)
plot_char = QTextCharFormat()
plot_char.setObjectType(QTextFormat.UserObject+1)
plot_char.setProperty(1, plot_img)
plot_char.setProperty(2, plot_num)
plot_char.setProperty(3, filename)
plot_char.setProperty(4, 0)
self.plotview.plot_tedit.textCursor().insertText("\ufffc", plot_char)
plot_image_dict[plot_num] = [plot_img, plot_num, filename, 0]
if __name__ == "__main__":
app = QApplication(sys.argv)
pte = PlotTextEditor()
pte.show()
sys.exit(app.exec_())