python3+PyQt5 实现Rich文本的行编辑方法
本文通过Python3+PyQt5实现《pythonQtGui快速编程》这本书13章程序Rich文本的行编辑,可以通过鼠标右键选择对文本进行加粗,斜体,下划线,删除线,上标,下标等编辑。
#!/usr/bin/envpython3
importplatform
importsys
importhtml
fromPyQt5.QtCoreimportQSize,Qt,pyqtSignal
fromPyQt5.QtGuiimportQColor,QFont,QFontMetrics,QIcon,QKeySequence,QPixmap,QTextCharFormat
fromPyQt5.QtWidgetsimportQAction,QApplication,QMenu,QTextEdit
classRichTextLineEdit(QTextEdit):
returnPressed=pyqtSignal()
(Bold,Italic,Underline,StrikeOut,Monospaced,Sans,Serif,
NoSuperOrSubscript,Subscript,Superscript)=range(10)
def__init__(self,parent=None):
super(RichTextLineEdit,self).__init__(parent)
self.monofamily="courier"
self.sansfamily="helvetica"
self.seriffamily="times"
self.setLineWrapMode(QTextEdit.NoWrap)
self.setTabChangesFocus(True)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
fm=QFontMetrics(self.font())
h=int(fm.height()*(1.4ifplatform.system()=="Windows"
else1.2))
self.setMinimumHeight(h)
self.setMaximumHeight(int(h*1.2))
self.setToolTip("PressCtrl+Mforthetexteffects"
"menuandCtrl+Kforthecolormenu")
deftoggleItalic(self):
self.setFontItalic(notself.fontItalic())
deftoggleUnderline(self):
self.setFontUnderline(notself.fontUnderline())
deftoggleBold(self):
self.setFontWeight(QFont.Normal
ifself.fontWeight()>QFont.NormalelseQFont.Bold)
defsizeHint(self):
returnQSize(self.document().idealWidth()+5,
self.maximumHeight())
defminimumSizeHint(self):
fm=QFontMetrics(self.font())
returnQSize(fm.width("WWWW"),self.minimumHeight())
defcontextMenuEvent(self,event):
self.textEffectMenu()
defkeyPressEvent(self,event):
ifevent.modifiers()&Qt.ControlModifier:
handled=False
ifevent.key()==Qt.Key_B:
self.toggleBold()
handled=True
elifevent.key()==Qt.Key_I:
self.toggleItalic()
handled=True
elifevent.key()==Qt.Key_K:
self.colorMenu()
handled=True
elifevent.key()==Qt.Key_M:
self.textEffectMenu()
handled=True
elifevent.key()==Qt.Key_U:
self.toggleUnderline()
handled=True
ifhandled:
event.accept()
return
ifevent.key()in(Qt.Key_Enter,Qt.Key_Return):
self.returnPressed.emit()
event.accept()
else:
QTextEdit.keyPressEvent(self,event)
defcolorMenu(self):
pixmap=QPixmap(22,22)
menu=QMenu("Colour")
fortext,colorin(
("&Black",Qt.black),
("B&lue",Qt.blue),
("DarkBl&ue",Qt.darkBlue),
("&Cyan",Qt.cyan),
("Dar&kCyan",Qt.darkCyan),
("&Green",Qt.green),
("DarkGr&een",Qt.darkGreen),
("M&agenta",Qt.magenta),
("DarkMage&nta",Qt.darkMagenta),
("&Red",Qt.red),
("&DarkRed",Qt.darkRed)):
color=QColor(color)
pixmap.fill(color)
action=menu.addAction(QIcon(pixmap),text,self.setColor)
action.setData(color)
self.ensureCursorVisible()
menu.exec_(self.viewport().mapToGlobal(
self.cursorRect().center()))
defsetColor(self):
action=self.sender()
ifactionisnotNoneandisinstance(action,QAction):
color=QColor(action.data())
ifcolor.isValid():
self.setTextColor(color)
deftextEffectMenu(self):
format=self.currentCharFormat()
menu=QMenu("TextEffect")
fortext,shortcut,data,checkedin(
("&Bold","Ctrl+B",RichTextLineEdit.Bold,
self.fontWeight()>QFont.Normal),
("&Italic","Ctrl+I",RichTextLineEdit.Italic,
self.fontItalic()),
("Strike&out",None,RichTextLineEdit.StrikeOut,
format.fontStrikeOut()),
("&Underline","Ctrl+U",RichTextLineEdit.Underline,
self.fontUnderline()),
("&Monospaced",None,RichTextLineEdit.Monospaced,
format.fontFamily()==self.monofamily),
("&Serifed",None,RichTextLineEdit.Serif,
format.fontFamily()==self.seriffamily),
("S&ansSerif",None,RichTextLineEdit.Sans,
format.fontFamily()==self.sansfamily),
("&Nosuperorsubscript",None,
RichTextLineEdit.NoSuperOrSubscript,
format.verticalAlignment()==
QTextCharFormat.AlignNormal),
("Su&perscript",None,RichTextLineEdit.Superscript,
format.verticalAlignment()==
QTextCharFormat.AlignSuperScript),
("Subs&cript",None,RichTextLineEdit.Subscript,
format.verticalAlignment()==
QTextCharFormat.AlignSubScript)):
action=menu.addAction(text,self.setTextEffect)
ifshortcutisnotNone:
action.setShortcut(QKeySequence(shortcut))
action.setData(data)
action.setCheckable(True)
action.setChecked(checked)
self.ensureCursorVisible()
menu.exec_(self.viewport().mapToGlobal(
self.cursorRect().center()))
defsetTextEffect(self):
action=self.sender()
ifactionisnotNoneandisinstance(action,QAction):
what=action.data()
ifwhat==RichTextLineEdit.Bold:
self.toggleBold()
return
ifwhat==RichTextLineEdit.Italic:
self.toggleItalic()
return
ifwhat==RichTextLineEdit.Underline:
self.toggleUnderline()
return
format=self.currentCharFormat()
ifwhat==RichTextLineEdit.Monospaced:
format.setFontFamily(self.monofamily)
elifwhat==RichTextLineEdit.Serif:
format.setFontFamily(self.seriffamily)
elifwhat==RichTextLineEdit.Sans:
format.setFontFamily(self.sansfamily)
ifwhat==RichTextLineEdit.StrikeOut:
format.setFontStrikeOut(notformat.fontStrikeOut())
ifwhat==RichTextLineEdit.NoSuperOrSubscript:
format.setVerticalAlignment(
QTextCharFormat.AlignNormal)
elifwhat==RichTextLineEdit.Superscript:
format.setVerticalAlignment(
QTextCharFormat.AlignSuperScript)
elifwhat==RichTextLineEdit.Subscript:
format.setVerticalAlignment(
QTextCharFormat.AlignSubScript)
self.mergeCurrentCharFormat(format)
deftoSimpleHtml(self):
htmltext=""
black=QColor(Qt.black)
block=self.document().begin()
whileblock.isValid():
iterator=block.begin()
whileiterator!=block.end():
fragment=iterator.fragment()
iffragment.isValid():
format=fragment.charFormat()
family=format.fontFamily()
color=format.foreground().color()
text=html.escape(fragment.text())
if(format.verticalAlignment()==
QTextCharFormat.AlignSubScript):
text="{0}".format(text)
elif(format.verticalAlignment()==
QTextCharFormat.AlignSuperScript):
text="{0}".format(text)
ifformat.fontUnderline():
text="{0}".format(text)
ifformat.fontItalic():
text="{0}".format(text)
ifformat.fontWeight()>QFont.Normal:
text="{0}".format(text)
ifformat.fontStrikeOut():
text="{0}".format(text)
ifcolor!=blackorfamily:
attribs=""
ifcolor!=black:
attribs+='color="{0}"'.format(color.name())
iffamily:
attribs+='face="{0}"'.format(family)
text="{1}".format(attribs,text)
htmltext+=text
iterator+=1
block=block.next()
returnhtmltext
if__name__=="__main__":
defprintout(lineedit):
print(str(lineedit.toHtml()))
print(str(lineedit.toPlainText()))
print(str(lineedit.toSimpleHtml()))
app=QApplication(sys.argv)
lineedit=RichTextLineEdit()
lineedit.returnPressed.connect(lambda:printout(lineedit))
lineedit.show()
lineedit.setWindowTitle("RichTextEdit")
app.exec_()
以上这篇python3+PyQt5实现Rich文本的行编辑方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。