在QScintilla插入编辑器中的图像
编辑:
标准QScintilla软件不支持此功能。但是Matic Kukovec做了一些攻击,无论如何得到它的工作。他的解决方案是在他的回答下面解释,也是对这个网页:https://qscintilla.com/insert-images/在QScintilla插入编辑器中的图像
我想在一个QScintilla编辑器中插入图像。不幸的是,这样的功能不会很快添加到官方的Scintilla项目中。看看这个职位上的Scintilla的,利益集团:
https://groups.google.com/forum/#!topic/scintilla-interest/Bwr4DY2Pv3Q
所以我必须实现它自己。我试了一下。请将以下代码复制到python文件中并运行它。只要确保你在同一个文件夹qscintilla_logo.png
图像,约80×80像素的:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.Qsci import *
# -----------------------------------
# | A sample of C-code, pasted into |
# | the QScintilla editor |
# -----------------------------------
myCodeSample = r"""#include <stdio.h>
/*
* I want an image
* right here =>
*/
int main()
{
char arr[5] = {'h', 'e', 'l', 'l', 'o'};
int i;
for(i = 0; i < 5; i++) {
printf(arr[i]);
}
return 0;
}""".replace("\n","\r\n")
# --------------------------------------------------
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# ---------------------------
# | Window setup |
# ---------------------------
# 1. Define the geometry of the main window
# ------------------------------------------
self.setGeometry(300, 300, 800, 400)
self.setWindowTitle("QScintilla Test")
# 2. Create frame and layout
# ---------------------------
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffeaeaea }")
self.__lyt = QVBoxLayout()
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myFont = QFont("Consolas", 14, weight=QFont.Bold)
self.__myFont.setPointSize(14)
# 3. Place a button
# ------------------
self.__btn = QPushButton("Qsci")
self.__btn.setFixedWidth(50)
self.__btn.setFixedHeight(50)
self.__btn.clicked.connect(self.__btn_action)
self.__btn.setFont(self.__myFont)
self.__lyt.addWidget(self.__btn)
# ---------------------------
# | QScintilla editor setup |
# ---------------------------
# 1. Make instance of QSciScintilla class
# ----------------------------------------
self.__editor = QsciScintilla()
self.__editor.setText(myCodeSample)
self.__editor.setLexer(None)
self.__editor.setUtf8(True) # Set encoding to UTF-8
self.__editor.setFont(self.__myFont) # Can be overridden by lexer
# 2. Create an image
# -------------------
self.__myImg = QPixmap("qscintilla_logo.png")
self.__myImgLbl = QLabel(parent=self.__editor)
self.__myImgLbl.setStyleSheet("QLabel { background-color : white; }");
self.__myImgLbl.setPixmap(self.__myImg)
self.__myImgLbl.move(300,80)
# 3. Add editor to layout
# ------------------------
self.__lyt.addWidget(self.__editor)
self.show()
''''''
def __btn_action(self):
print("Hello World!")
''''''
''' End Class '''
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
''''''
当运行Python脚本,你应该得到以下结果:
实际上,我对编辑顶部添加一个QLabel ,并给它一个绝对位置:
self.__myImgLbl = QLabel(parent=self.__editor)
self.__myImgLbl.move(300,80)
不幸的是,向下滚动时图像不动:
我想我知道这是为什么。让我解释。该编辑器是QsciScintilla
类,这是QsciScintillaBase
一个子类,这是QAbstractScrollArea
一个子类的对象:
我认为,成功的关键是增加了QLabel到小部件内QAbstractScrollArea
,而不是滚动区域本身。我已经尝试了几件事来找到这个小部件,但没有成功。
如果它是QScrollArea
,那么函数widget()
就足够了。但是该功能在QAbstractScrollArea
上不可用。
EDIT 1:
的Python代码示例中的编辑器不执行任何语法突出显示,甚至不具有行号。那是因为我只想关注实际问题 - 添加图像。该代码示例是基于:
编辑2:
请,请从在编辑器中插入图像是否是好还是坏主意提出意见避免。让我们继续关注技术问题。
嘿克里斯托夫试试这个(你有一些修改为例):
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.Qsci import *
# -----------------------------------
# | A sample of C-code, pasted into |
# | the QScintilla editor |
# -----------------------------------
myCodeSample = r"""#include <stdio.h>
/*
* I want an image
* right here =>
*/
int main()
{
char arr[5] = {'h', 'e', 'l', 'l', 'o'};
int i;
for(i = 0; i < 5; i++) {
printf(arr[i]);
}
return 0;
}""".replace("\n","\r\n")
# --------------------------------------------------
class MyScintilla(QsciScintilla):
def __init__(self, parent=None):
super().__init__(parent)
self.image = QImage("qscintilla_logo.png")
def paintEvent(self, e):
super().paintEvent(e)
# Get paint rectangle size
current_parent_size = self.size()
image_line = 4
image_column = 17
# Find the paint offset
line_height = 20
font_width = 10
first_visible_line = self.SendScintilla(self.SCI_GETFIRSTVISIBLELINE)
paint_offset_x = image_column * font_width
paint_offset_y = (image_line - first_visible_line) * line_height
# Paint the image
painter = QPainter()
painter.begin(self.viewport())
painter.drawImage(QPoint(paint_offset_x,paint_offset_y), self.image)
painter.end()
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# ---------------------------
# | Window setup |
# ---------------------------
# 1. Define the geometry of the main window
# ------------------------------------------
self.setGeometry(300, 300, 800, 400)
self.setWindowTitle("QScintilla Test")
# 2. Create frame and layout
# ---------------------------
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffeaeaea }")
self.__lyt = QVBoxLayout()
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myFont = QFont("Consolas", 14, weight=QFont.Bold)
self.__myFont.setPointSize(14)
# 3. Place a button
# ------------------
self.__btn = QPushButton("Qsci")
self.__btn.setFixedWidth(50)
self.__btn.setFixedHeight(50)
self.__btn.clicked.connect(self.__btn_action)
self.__btn.setFont(self.__myFont)
self.__lyt.addWidget(self.__btn)
# ---------------------------
# | QScintilla editor setup |
# ---------------------------
# 1. Make instance of QSciScintilla class
# ----------------------------------------
self.__editor = MyScintilla()
self.__editor.setText(myCodeSample)
self.__editor.setLexer(None)
self.__editor.setUtf8(True) # Set encoding to UTF-8
self.__editor.setFont(self.__myFont) # Can be overridden by lexer
# 3. Add editor to layout
# ------------------------
self.__lyt.addWidget(self.__editor)
self.show()
''''''
def __btn_action(self):
print("Hello World!")
''''''
''' End Class '''
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
''''''
它只是继承了QsciScintilla类和重载它的的paintEvent方法。 诀窍是获取图像相对于文档视图的坐标。对于我猜测的线路高度和字体宽度的例子,它可能可以从QScintilla中获得。 另一件事是我只是用行和列偏移硬编码图像的位置,创建一个编辑器可以自动解析和插入图像的语法可能会很好。
Regards
谢谢马蒂奇! –
你试图实现这个的方式永远不会工作。小部件布局和文档布局是两个完全分开的东西。没有办法解决这个问题,因为Scintilla不支持将图像添加到文档布局。如果你真的想要这个功能,你需要寻找一个不同的代码编辑器小部件。 – ekhumoro
谢谢ekhumoro您的评论。 “小部件布局”和“文档布局”是什么意思?我不会将图像添加到任何布局。事实上,我在它的“父”控件上给它一个绝对的位置。现在,我传递QScintilla编辑器作为父项,因为我没有别的。但我相信传递QScintilla编辑器的一个子部件 - 即滚动的部件 - 就是解决方案。 –
如果用户在编辑器顶部插入/删除10行,您会发生什么?图像没有嵌入到文档布局中,因此在编辑文本时不会移动。如果你想嵌入图像,使用通用的富文本小部件,如'QTextEdit'。 – ekhumoro