python

超轻量级php框架startmvc

python3+PyQt5 实现Rich文本的行编辑方法

更新时间:2020-07-06 20:30:01 作者:startmvc
本文通过Python3+PyQt5实现《pythonQtGui快速编程》这本书13章程序Rich文本的行编辑,可以通过鼠

本文通过Python3+PyQt5实现《python Qt Gui 快速编程》这本书13章程序Rich文本的行编辑,可以通过鼠标右键选择对文本进行加粗,斜体,下划线,删除线,上标,下标等编辑。


#!/usr/bin/env python3

import platform
import sys
import html
from PyQt5.QtCore import QSize, Qt,pyqtSignal
from PyQt5.QtGui import QColor, QFont,QFontMetrics, QIcon, QKeySequence, QPixmap,QTextCharFormat
from PyQt5.QtWidgets import QAction,QApplication,QMenu,QTextEdit



class RichTextLineEdit(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.4 if platform.system() == "Windows"
 else 1.2))
 self.setMinimumHeight(h)
 self.setMaximumHeight(int(h * 1.2))
 self.setToolTip("Press <b>Ctrl+M</b> for the text effects "
 "menu and <b>Ctrl+K</b> for the color menu")


 def toggleItalic(self):
 self.setFontItalic(not self.fontItalic())


 def toggleUnderline(self):
 self.setFontUnderline(not self.fontUnderline())


 def toggleBold(self):
 self.setFontWeight(QFont.Normal
 if self.fontWeight() > QFont.Normal else QFont.Bold)


 def sizeHint(self):
 return QSize(self.document().idealWidth() + 5,
 self.maximumHeight())


 def minimumSizeHint(self):
 fm = QFontMetrics(self.font())
 return QSize(fm.width("WWWW"), self.minimumHeight())


 def contextMenuEvent(self, event):
 self.textEffectMenu()


 def keyPressEvent(self, event):
 if event.modifiers() & Qt.ControlModifier:
 handled = False
 if event.key() == Qt.Key_B:
 self.toggleBold()
 handled = True
 elif event.key() == Qt.Key_I:
 self.toggleItalic()
 handled = True
 elif event.key() == Qt.Key_K:
 self.colorMenu()
 handled = True
 elif event.key() == Qt.Key_M:
 self.textEffectMenu()
 handled = True
 elif event.key() == Qt.Key_U:
 self.toggleUnderline()
 handled = True
 if handled:
 event.accept()
 return
 if event.key() in (Qt.Key_Enter, Qt.Key_Return):
 self.returnPressed.emit()
 event.accept()
 else:
 QTextEdit.keyPressEvent(self, event)


 def colorMenu(self):
 pixmap = QPixmap(22, 22)
 menu = QMenu("Colour")
 for text, color in (
 ("&Black", Qt.black),
 ("B&lue", Qt.blue),
 ("Dark Bl&ue", Qt.darkBlue),
 ("&Cyan", Qt.cyan),
 ("Dar&k Cyan", Qt.darkCyan),
 ("&Green", Qt.green),
 ("Dark Gr&een", Qt.darkGreen),
 ("M&agenta", Qt.magenta),
 ("Dark Mage&nta", Qt.darkMagenta),
 ("&Red", Qt.red),
 ("&Dark Red", 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()))


 def setColor(self):
 action = self.sender()
 if action is not None and isinstance(action, QAction):
 color = QColor(action.data())
 if color.isValid():
 self.setTextColor(color)


 def textEffectMenu(self):
 format = self.currentCharFormat()
 menu = QMenu("Text Effect")
 for text, shortcut, data, checked in (
 ("&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&ans Serif", None, RichTextLineEdit.Sans,
 format.fontFamily() == self.sansfamily),
 ("&No super or subscript", 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)
 if shortcut is not None:
 action.setShortcut(QKeySequence(shortcut))
 action.setData(data)
 action.setCheckable(True)
 action.setChecked(checked)
 self.ensureCursorVisible()
 menu.exec_(self.viewport().mapToGlobal(
 self.cursorRect().center()))


 def setTextEffect(self):
 action = self.sender()
 if action is not None and isinstance(action, QAction):
 what = action.data()
 if what == RichTextLineEdit.Bold:
 self.toggleBold()
 return
 if what == RichTextLineEdit.Italic:
 self.toggleItalic()
 return
 if what == RichTextLineEdit.Underline:
 self.toggleUnderline()
 return
 format = self.currentCharFormat()
 if what == RichTextLineEdit.Monospaced:
 format.setFontFamily(self.monofamily)
 elif what == RichTextLineEdit.Serif:
 format.setFontFamily(self.seriffamily)
 elif what == RichTextLineEdit.Sans:
 format.setFontFamily(self.sansfamily)
 if what == RichTextLineEdit.StrikeOut:
 format.setFontStrikeOut(not format.fontStrikeOut())
 if what == RichTextLineEdit.NoSuperOrSubscript:
 format.setVerticalAlignment(
 QTextCharFormat.AlignNormal)
 elif what == RichTextLineEdit.Superscript:
 format.setVerticalAlignment(
 QTextCharFormat.AlignSuperScript)
 elif what == RichTextLineEdit.Subscript:
 format.setVerticalAlignment(
 QTextCharFormat.AlignSubScript)
 self.mergeCurrentCharFormat(format)


 def toSimpleHtml(self):
 htmltext = ""
 black = QColor(Qt.black)
 block = self.document().begin()
 while block.isValid():
 iterator = block.begin()
 while iterator != block.end():
 fragment = iterator.fragment()
 if fragment.isValid():
 format = fragment.charFormat()
 family = format.fontFamily()
 color = format.foreground().color() 
 text=html.escape(fragment.text())
 if (format.verticalAlignment() ==
 QTextCharFormat.AlignSubScript):
 text = "<sub>{0}</sub>".format(text)
 elif (format.verticalAlignment() ==
 QTextCharFormat.AlignSuperScript):
 text = "<sup>{0}</sup>".format(text)
 if format.fontUnderline():
 text = "<u>{0}</u>".format(text)
 if format.fontItalic():
 text = "<i>{0}</i>".format(text)
 if format.fontWeight() > QFont.Normal:
 text = "<b>{0}</b>".format(text)
 if format.fontStrikeOut():
 text = "<s>{0}</s>".format(text)
 if color != black or family:
 attribs = ""
 if color != black:
 attribs += ' color="{0}"'.format(color.name())
 if family:
 attribs += ' face="{0}"'.format(family)
 text = "<font{0}>{1}</font>".format(attribs,text)
 htmltext += text
 iterator += 1
 block = block.next()
 return htmltext

if __name__ == "__main__":
 def printout(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文本的行编辑方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

python3 PyQt5 Rich 文本 行编辑