本文通过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文本的行编辑方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?