经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Python3 » 查看文章
python3+PyQt5 实现Rich文本的行编辑方法
来源:jb51  时间:2019/6/18 8:37:40  对本文有异议

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

  1. #!/usr/bin/env python3
  2.  
  3. import platform
  4. import sys
  5. import html
  6. from PyQt5.QtCore import QSize, Qt,pyqtSignal
  7. from PyQt5.QtGui import QColor, QFont,QFontMetrics, QIcon, QKeySequence, QPixmap,QTextCharFormat
  8. from PyQt5.QtWidgets import QAction,QApplication,QMenu,QTextEdit
  9.  
  10.  
  11.  
  12. class RichTextLineEdit(QTextEdit):
  13. returnPressed=pyqtSignal()
  14. (Bold, Italic, Underline, StrikeOut, Monospaced, Sans, Serif,
  15. NoSuperOrSubscript, Subscript, Superscript) = range(10)
  16.  
  17.  
  18. def __init__(self, parent=None):
  19. super(RichTextLineEdit, self).__init__(parent)
  20.  
  21. self.monofamily = "courier"
  22. self.sansfamily = "helvetica"
  23. self.seriffamily = "times"
  24. self.setLineWrapMode(QTextEdit.NoWrap)
  25. self.setTabChangesFocus(True)
  26. self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
  27. self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
  28. fm = QFontMetrics(self.font())
  29. h = int(fm.height() * (1.4 if platform.system() == "Windows"
  30. else 1.2))
  31. self.setMinimumHeight(h)
  32. self.setMaximumHeight(int(h * 1.2))
  33. self.setToolTip("Press <b>Ctrl+M</b> for the text effects "
  34. "menu and <b>Ctrl+K</b> for the color menu")
  35.  
  36.  
  37. def toggleItalic(self):
  38. self.setFontItalic(not self.fontItalic())
  39.  
  40.  
  41. def toggleUnderline(self):
  42. self.setFontUnderline(not self.fontUnderline())
  43.  
  44.  
  45. def toggleBold(self):
  46. self.setFontWeight(QFont.Normal
  47. if self.fontWeight() > QFont.Normal else QFont.Bold)
  48.  
  49.  
  50. def sizeHint(self):
  51. return QSize(self.document().idealWidth() + 5,
  52. self.maximumHeight())
  53.  
  54.  
  55. def minimumSizeHint(self):
  56. fm = QFontMetrics(self.font())
  57. return QSize(fm.width("WWWW"), self.minimumHeight())
  58.  
  59.  
  60. def contextMenuEvent(self, event):
  61. self.textEffectMenu()
  62.  
  63.  
  64. def keyPressEvent(self, event):
  65. if event.modifiers() & Qt.ControlModifier:
  66. handled = False
  67. if event.key() == Qt.Key_B:
  68. self.toggleBold()
  69. handled = True
  70. elif event.key() == Qt.Key_I:
  71. self.toggleItalic()
  72. handled = True
  73. elif event.key() == Qt.Key_K:
  74. self.colorMenu()
  75. handled = True
  76. elif event.key() == Qt.Key_M:
  77. self.textEffectMenu()
  78. handled = True
  79. elif event.key() == Qt.Key_U:
  80. self.toggleUnderline()
  81. handled = True
  82. if handled:
  83. event.accept()
  84. return
  85. if event.key() in (Qt.Key_Enter, Qt.Key_Return):
  86. self.returnPressed.emit()
  87. event.accept()
  88. else:
  89. QTextEdit.keyPressEvent(self, event)
  90.  
  91.  
  92. def colorMenu(self):
  93. pixmap = QPixmap(22, 22)
  94. menu = QMenu("Colour")
  95. for text, color in (
  96. ("&Black", Qt.black),
  97. ("B&lue", Qt.blue),
  98. ("Dark Bl&ue", Qt.darkBlue),
  99. ("&Cyan", Qt.cyan),
  100. ("Dar&k Cyan", Qt.darkCyan),
  101. ("&Green", Qt.green),
  102. ("Dark Gr&een", Qt.darkGreen),
  103. ("M&agenta", Qt.magenta),
  104. ("Dark Mage&nta", Qt.darkMagenta),
  105. ("&Red", Qt.red),
  106. ("&Dark Red", Qt.darkRed)):
  107. color = QColor(color)
  108. pixmap.fill(color)
  109. action = menu.addAction(QIcon(pixmap), text, self.setColor)
  110. action.setData(color)
  111. self.ensureCursorVisible()
  112. menu.exec_(self.viewport().mapToGlobal(
  113. self.cursorRect().center()))
  114.  
  115.  
  116. def setColor(self):
  117. action = self.sender()
  118. if action is not None and isinstance(action, QAction):
  119. color = QColor(action.data())
  120. if color.isValid():
  121. self.setTextColor(color)
  122.  
  123.  
  124. def textEffectMenu(self):
  125. format = self.currentCharFormat()
  126. menu = QMenu("Text Effect")
  127. for text, shortcut, data, checked in (
  128. ("&Bold", "Ctrl+B", RichTextLineEdit.Bold,
  129. self.fontWeight() > QFont.Normal),
  130. ("&Italic", "Ctrl+I", RichTextLineEdit.Italic,
  131. self.fontItalic()),
  132. ("Strike &out", None, RichTextLineEdit.StrikeOut,
  133. format.fontStrikeOut()),
  134. ("&Underline", "Ctrl+U", RichTextLineEdit.Underline,
  135. self.fontUnderline()),
  136. ("&Monospaced", None, RichTextLineEdit.Monospaced,
  137. format.fontFamily() == self.monofamily),
  138. ("&Serifed", None, RichTextLineEdit.Serif,
  139. format.fontFamily() == self.seriffamily),
  140. ("S&ans Serif", None, RichTextLineEdit.Sans,
  141. format.fontFamily() == self.sansfamily),
  142. ("&No super or subscript", None,
  143. RichTextLineEdit.NoSuperOrSubscript,
  144. format.verticalAlignment() ==
  145. QTextCharFormat.AlignNormal),
  146. ("Su&perscript", None, RichTextLineEdit.Superscript,
  147. format.verticalAlignment() ==
  148. QTextCharFormat.AlignSuperScript),
  149. ("Subs&cript", None, RichTextLineEdit.Subscript,
  150. format.verticalAlignment() ==
  151. QTextCharFormat.AlignSubScript)):
  152. action = menu.addAction(text, self.setTextEffect)
  153. if shortcut is not None:
  154. action.setShortcut(QKeySequence(shortcut))
  155. action.setData(data)
  156. action.setCheckable(True)
  157. action.setChecked(checked)
  158. self.ensureCursorVisible()
  159. menu.exec_(self.viewport().mapToGlobal(
  160. self.cursorRect().center()))
  161.  
  162.  
  163. def setTextEffect(self):
  164. action = self.sender()
  165. if action is not None and isinstance(action, QAction):
  166. what = action.data()
  167. if what == RichTextLineEdit.Bold:
  168. self.toggleBold()
  169. return
  170. if what == RichTextLineEdit.Italic:
  171. self.toggleItalic()
  172. return
  173. if what == RichTextLineEdit.Underline:
  174. self.toggleUnderline()
  175. return
  176. format = self.currentCharFormat()
  177. if what == RichTextLineEdit.Monospaced:
  178. format.setFontFamily(self.monofamily)
  179. elif what == RichTextLineEdit.Serif:
  180. format.setFontFamily(self.seriffamily)
  181. elif what == RichTextLineEdit.Sans:
  182. format.setFontFamily(self.sansfamily)
  183. if what == RichTextLineEdit.StrikeOut:
  184. format.setFontStrikeOut(not format.fontStrikeOut())
  185. if what == RichTextLineEdit.NoSuperOrSubscript:
  186. format.setVerticalAlignment(
  187. QTextCharFormat.AlignNormal)
  188. elif what == RichTextLineEdit.Superscript:
  189. format.setVerticalAlignment(
  190. QTextCharFormat.AlignSuperScript)
  191. elif what == RichTextLineEdit.Subscript:
  192. format.setVerticalAlignment(
  193. QTextCharFormat.AlignSubScript)
  194. self.mergeCurrentCharFormat(format)
  195.  
  196.  
  197. def toSimpleHtml(self):
  198. htmltext = ""
  199. black = QColor(Qt.black)
  200. block = self.document().begin()
  201. while block.isValid():
  202. iterator = block.begin()
  203. while iterator != block.end():
  204. fragment = iterator.fragment()
  205. if fragment.isValid():
  206. format = fragment.charFormat()
  207. family = format.fontFamily()
  208. color = format.foreground().color()
  209. text=html.escape(fragment.text())
  210. if (format.verticalAlignment() ==
  211. QTextCharFormat.AlignSubScript):
  212. text = "<sub>{0}</sub>".format(text)
  213. elif (format.verticalAlignment() ==
  214. QTextCharFormat.AlignSuperScript):
  215. text = "<sup>{0}</sup>".format(text)
  216. if format.fontUnderline():
  217. text = "<u>{0}</u>".format(text)
  218. if format.fontItalic():
  219. text = "<i>{0}</i>".format(text)
  220. if format.fontWeight() > QFont.Normal:
  221. text = "<b>{0}</b>".format(text)
  222. if format.fontStrikeOut():
  223. text = "<s>{0}</s>".format(text)
  224. if color != black or family:
  225. attribs = ""
  226. if color != black:
  227. attribs += ' color="{0}"'.format(color.name())
  228. if family:
  229. attribs += ' face="{0}"'.format(family)
  230. text = "<font{0}>{1}</font>".format(attribs,text)
  231. htmltext += text
  232. iterator += 1
  233. block = block.next()
  234. return htmltext
  235.  
  236. if __name__ == "__main__":
  237. def printout(lineedit):
  238. print(str(lineedit.toHtml()))
  239. print(str(lineedit.toPlainText()))
  240. print(str(lineedit.toSimpleHtml()))
  241. app = QApplication(sys.argv)
  242. lineedit = RichTextLineEdit()
  243. lineedit.returnPressed.connect(lambda:printout(lineedit))
  244. lineedit.show()
  245. lineedit.setWindowTitle("RichTextEdit")
  246. app.exec_()

以上这篇python3+PyQt5 实现Rich文本的行编辑方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号