• 技术文章 >后端开发 >Python教程

    python3+PyQt5泛型委托详解

    不言不言2018-04-24 11:24:55原创1399
    这篇文章主要为大家详细介绍了python3+PyQt5泛型委托的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    自定义委托可以让我们对视图中出现的数据项的外观和行为进行完全控制。如果有很多模型,可能会希望不是全部的大多数模型能够仅用一个自定义委托,如果不能这么做,那么对于这些自定义委托,将很有可能存在大量重复代码。为了使得维护工作变得轻松,更好的方法为不要为每个模型创建一个自定义委托,而是用一系列的通用组件来共同构成一个委托。本文通过Python3+pyqt5实现了python Qt GUI 快速编程的16章的泛型委托例子。

    /home/yrd/eric_workspace/chap16/richtextlineedit.py

    #!/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_()

    /home/yrd/eric_workspace/chap16/genericdelegates.py


    #!/usr/bin/env python3
    
    from PyQt5.QtCore import (QDate, QSize, Qt)
    from PyQt5.QtWidgets import (QApplication, QDateEdit, QLineEdit,
      QSpinBox, QStyledItemDelegate,QStyle)
    from PyQt5.QtGui import QColor,QTextDocument
    import richtextlineedit
    
    
    class GenericDelegate(QStyledItemDelegate):
    
     def __init__(self, parent=None):
      super(GenericDelegate, self).__init__(parent)
      self.delegates = {}
    
    
     def insertColumnDelegate(self, column, delegate):
      delegate.setParent(self)
      self.delegates[column] = delegate
    
    
     def removeColumnDelegate(self, column):
      if column in self.delegates:
       del self.delegates[column]
    
    
     def paint(self, painter, option, index):
      delegate = self.delegates.get(index.column())
      if delegate is not None:
       delegate.paint(painter, option, index)
      else:
       QStyledItemDelegate.paint(self, painter, option, index)
    
    
     def createEditor(self, parent, option, index):
      delegate = self.delegates.get(index.column())
      if delegate is not None:
       return delegate.createEditor(parent, option, index)
      else:
       return QStyledItemDelegate.createEditor(self, parent, option,
                 index)
    
    
     def setEditorData(self, editor, index):
      delegate = self.delegates.get(index.column())
      if delegate is not None:
       delegate.setEditorData(editor, index)
      else:
       QStyledItemDelegate.setEditorData(self, editor, index)
    
    
     def setModelData(self, editor, model, index):
      delegate = self.delegates.get(index.column())
      if delegate is not None:
       delegate.setModelData(editor, model, index)
      else:
       QStyledItemDelegate.setModelData(self, editor, model, index)
    
    
    class IntegerColumnDelegate(QStyledItemDelegate):
    
     def __init__(self, minimum=0, maximum=100, parent=None):
      super(IntegerColumnDelegate, self).__init__(parent)
      self.minimum = minimum
      self.maximum = maximum
    
    
     def createEditor(self, parent, option, index):
      spinbox = QSpinBox(parent)
      spinbox.setRange(self.minimum, self.maximum)
      spinbox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
      return spinbox
    
    
     def setEditorData(self, editor, index):
      value = index.model().data(index, Qt.DisplayRole)
      editor.setValue(value)
    
    
     def setModelData(self, editor, model, index):
      editor.interpretText()
      model.setData(index, editor.value())
    
    
    class DateColumnDelegate(QStyledItemDelegate):
    
     def __init__(self, minimum=QDate(),
         maximum=QDate.currentDate(),
         format="yyyy-MM-dd", parent=None):
      super(DateColumnDelegate, self).__init__(parent)
      self.minimum = minimum
      self.maximum = maximum
      self.format = format
    
    
     def createEditor(self, parent, option, index):
      dateedit = QDateEdit(parent)
      #dateedit=QDateTimeEdit(parent)
      dateedit.setDateRange(self.minimum, self.maximum)
      dateedit.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
      dateedit.setDisplayFormat(self.format)
      dateedit.setCalendarPopup(True)
      return dateedit
    
    
     def setEditorData(self, editor, index):
      value = index.model().data(index, Qt.DisplayRole)
      #if value.isNull:
      editor.setDate(value)
      #editor.setDisplayFormat(self.format)
    
     def setModelData(self, editor, model, index):
      model.setData(index, editor.date())
     def paint(self, painter, option, index):
      text = index.model().data(index, Qt.DisplayRole).toString(self.format)
      palette = QApplication.palette()
      document = QTextDocument()
      document.setDefaultFont(option.font)
      if option.state & QStyle.State_Selected:
       document.setHtml("<font color={0}>{1}</font>".format(palette.highlightedText().color().name(),text))
      else:
       document.setHtml(text)
      painter.save()
      color = (palette.highlight().color()
         if option.state & QStyle.State_Selected
         else QColor(index.model().data(index,
            Qt.BackgroundColorRole)))
      painter.fillRect(option.rect, color)
      painter.translate(option.rect.x(), option.rect.y())
      document.drawContents(painter)
      painter.restore()  
    
    
    class PlainTextColumnDelegate(QStyledItemDelegate):
    
     def __init__(self, parent=None):
      super(PlainTextColumnDelegate, self).__init__(parent)
    
    
     def createEditor(self, parent, option, index):
      lineedit = QLineEdit(parent)
      return lineedit
    
    
     def setEditorData(self, editor, index):
      value = index.model().data(index, Qt.DisplayRole)
      editor.setText(value)
    
    
     def setModelData(self, editor, model, index):
      model.setData(index, editor.text())
    
    
    class RichTextColumnDelegate(QStyledItemDelegate):
    
     def __init__(self, parent=None):
      super(RichTextColumnDelegate, self).__init__(parent)
    
    
     def paint(self, painter, option, index):
      text = index.model().data(index, Qt.DisplayRole)
      palette = QApplication.palette()
      document = QTextDocument()
      document.setDefaultFont(option.font)
      if option.state & QStyle.State_Selected:
       document.setHtml("<font color={0}>{1}</font>".format(palette.highlightedText().color().name(),text))
      else:
       document.setHtml(text)
      painter.save()
      color = (palette.highlight().color()
         if option.state & QStyle.State_Selected
         else QColor(index.model().data(index,
            Qt.BackgroundColorRole)))
      painter.fillRect(option.rect, color)
      painter.translate(option.rect.x(), option.rect.y())
      document.drawContents(painter)
      painter.restore()
    
    
     def sizeHint(self, option, index):
      text = index.model().data(index).toString()
      document = QTextDocument()
      document.setDefaultFont(option.font)
      document.setHtml(text)
      return QSize(document.idealWidth() + 5,
          option.fontMetrics.height())
    
    
     def createEditor(self, parent, option, index):
      lineedit = richtextlineedit.RichTextLineEdit(parent)
      return lineedit
    
    
     def setEditorData(self, editor, index):
      value = index.model().data(index, Qt.DisplayRole)
      editor.setHtml(value)
    
    
     def setModelData(self, editor, model, index):
      model.setData(index, editor.toSimpleHtml())

    /home/yrd/eric_workspace/chap16/carhirelog.pyw


    #!/usr/bin/env python3
    
    import bisect
    import os
    import platform
    import sys
    from PyQt5.QtCore import (QAbstractTableModel, QDate, QModelIndex,
      QVariant, Qt,pyqtSignal)
    from PyQt5.QtWidgets import (QApplication, QMainWindow,
      QShortcut, QTableView)
    from PyQt5.QtGui import QKeySequence
    import genericdelegates
    
    
    (LICENSE, CUSTOMER, HIRED, MILEAGEOUT, RETURNED, MILEAGEBACK,
     NOTES, MILEAGE, DAYS) = range(9)
    
    
    class CarHireLog(object):
    
     def __init__(self, license, customer, hired, mileageout,
         returned=QDate(), mileageback=0, notes=""):
      self.license = license  # plain text
      self.customer = customer # plain text
      self.hired = hired     # QDate
      self.mileageout = mileageout   # int
      self.returned = returned    # QDate
      self.mileageback = mileageback  # int
      self.notes = notes   # HTML
    
    
     def field(self, column):
      if column == LICENSE:
       return self.license
      elif column == CUSTOMER:
       return self.customer
      elif column == HIRED:
       return self.hired
      elif column == MILEAGEOUT:
       return self.mileageout
      elif column == RETURNED:
       return self.returned
      elif column == MILEAGEBACK:
       return self.mileageback
      elif column == NOTES:
       return self.notes
      elif column == MILEAGE:
       return self.mileage()
      elif column == DAYS:
       return self.days()
      assert False
    
    
     def mileage(self):
      return (0 if self.mileageback == 0
         else self.mileageback - self.mileageout)
    
    
     def days(self):
      return (0 if not self.returned.isValid()
         else self.hired.daysTo(self.returned))
    
    
     def __hash__(self):
      return super(CarHireLog, self).__hash__()
    
    
     def __eq__(self, other):
      if self.hired != other.hired:
       return False
      if self.customer != other.customer:
       return False
      if self.license != other.license:
       return False
      return id(self) == id(other)
    
    
     def __lt__(self, other):
      if self.hired < other.hired:
       return True
      if self.customer < other.customer:
       return True
      if self.license < other.license:
       return True
      return id(self) < id(other)
    
    
    class CarHireModel(QAbstractTableModel):
     dataChanged = pyqtSignal(QModelIndex,QModelIndex)
     def __init__(self, parent=None):
      super(CarHireModel, self).__init__(parent)
      self.logs = []
    
      # Generate fake data
      import gzip
      import random
      import string
      surname_data = gzip.open(os.path.join(
        os.path.dirname(__file__), "surnames.txt.gz")).read()
      surnames = surname_data.decode("utf8").splitlines()
      years = ("06 ", "56 ", "07 ", "57 ", "08 ", "58 ")
      titles = ("Ms ", "Mr ", "Ms ", "Mr ", "Ms ", "Mr ", "Dr ")
      notetexts = ("Returned <font color=red><b>damaged</b></font>",
        "Returned with <i>empty fuel tank</i>",
        "Customer <b>complained</b> about the <u>engine</u>",
        "Customer <b>complained</b> about the <u>gears</u>",
        "Customer <b>complained</b> about the <u>clutch</u>",
        "Returned <font color=darkred><b>dirty</b></font>",)
      today = QDate.currentDate()
      for i in range(250):
       license = []
       for c in range(5):
        license.append(random.choice(string.ascii_uppercase))
       license = ("".join(license[:2]) + random.choice(years) +
          "".join(license[2:]))
       customer = random.choice(titles) + random.choice(surnames)
       hired = today.addDays(-random.randint(0, 365))
       mileageout = random.randint(10000, 30000)
       notes = ""
       if random.random() >= 0.2:
        days = random.randint(1, 21)
        returned = hired.addDays(days)
        mileageback = (mileageout +
            (days * random.randint(30, 300)))
        if random.random() > 0.75:
         notes = random.choice(notetexts)
       else:
        returned = QDate()
        mileageback = 0
       log = CarHireLog(license, customer, hired, mileageout,
            returned, mileageback, notes)
       bisect.insort(self.logs, log)
    
    
     def rowCount(self, index=QModelIndex()):
      return len(self.logs)
    
    
     def columnCount(self, index=QModelIndex()):
      return 9
    
    
     def data(self, index, role):
      if not index.isValid():
       return QVariant()
      if role == Qt.DisplayRole:
       log = self.logs[index.row()]
       value = log.field(index.column())
       if (index.column() in (MILEAGEBACK, MILEAGE, DAYS) and
        value == 0):
        return 0
       return value
      if (role == Qt.TextAlignmentRole and
       index.column() not in (LICENSE, CUSTOMER, NOTES)):
       return QVariant(int(Qt.AlignRight|Qt.AlignVCenter))
      if role == Qt.BackgroundColorRole:
       palette = QApplication.palette()
       if index.column() in (LICENSE, MILEAGE, DAYS):
        return QVariant(palette.alternateBase())
       else:
        return QVariant(palette.base())
      return QVariant()
    
    
     def setData(self, index, value, role=Qt.EditRole):
      if (index.isValid() and role == Qt.EditRole and
       index.column() not in (LICENSE, MILEAGE, DAYS)):
       log = self.logs[index.row()]
       column = index.column()
       if column == CUSTOMER:
        log.customer = value
       elif column == HIRED:
        #log.hired = value.toDate()
        log.hired = value
       elif column == MILEAGEOUT:
        log.mileageout = value
       elif column == RETURNED:
        #log.returned = value.toDate()
        log.returned = value
       elif column == MILEAGEBACK:
        log.mileageback = value
       elif column == NOTES:
        log.notes = value
       self.dataChanged[QModelIndex,QModelIndex].emit(index,index)
       return True
      return False
    
    
     def headerData(self, section, orientation, role):
      if role == Qt.TextAlignmentRole:
       if orientation == Qt.Horizontal:
        return QVariant(int(Qt.AlignCenter))
       return QVariant(int(Qt.AlignRight|Qt.AlignVCenter))
      if role != Qt.DisplayRole:
       return QVariant()
      if orientation == Qt.Horizontal:
       if section == LICENSE:
        return "License"
       elif section == CUSTOMER:
        return "Customer"
       elif section == HIRED:
        return "Hired"
       elif section == MILEAGEOUT:
        return "Mileage #1"
       elif section == RETURNED:
        return "Returned"
       elif section == MILEAGEBACK:
        return "Mileage #2"
       elif section == DAYS:
        return "Days"
       elif section == MILEAGE:
        return "Miles"
       elif section == NOTES:
        return "Notes"
      return section + 1
    
    
     def flags(self, index):
      flag = QAbstractTableModel.flags(self, index)
      if index.column() not in (LICENSE, MILEAGE, DAYS):
       flag |= Qt.ItemIsEditable
      return flag
    
    
    class HireDateColumnDelegate(genericdelegates.DateColumnDelegate):
    
     def createEditor(self, parent, option, index):
      i = index.sibling(index.row(), RETURNED)
      self.maximum = i.model().data(i, Qt.DisplayRole).addDays(-1)
      return genericdelegates.DateColumnDelegate.createEditor(
        self, parent, option, index)
    
    
    class ReturnDateColumnDelegate(genericdelegates.DateColumnDelegate):
    
     def createEditor(self, parent, option, index):
      i = index.sibling(index.row(), HIRED)
      self.minimum = i.model().data(i, Qt.DisplayRole).addDays(1)
      return genericdelegates.DateColumnDelegate.createEditor(
        self, parent, option, index)
    
    
    class MileageOutColumnDelegate(genericdelegates.IntegerColumnDelegate):
    
     def createEditor(self, parent, option, index):
      i = index.sibling(index.row(), MILEAGEBACK)
      maximum = i.model().data(i, Qt.DisplayRole)
      self.maximum = 1000000 if maximum == 0 else maximum - 1
      return genericdelegates.IntegerColumnDelegate.createEditor(
        self, parent, option, index)
    
    
    class MileageBackColumnDelegate(genericdelegates.IntegerColumnDelegate):
    
     def createEditor(self, parent, option, index):
      i = index.sibling(index.row(), MILEAGEOUT)
      self.minimum = i.model().data(i, Qt.DisplayRole) + 1
      return genericdelegates.IntegerColumnDelegate.createEditor(
        self, parent, option, index)
    
    
    class MainForm(QMainWindow):
    
     def __init__(self, parent=None):
      super(MainForm, self).__init__(parent)
    
      model = CarHireModel(self)
    
      self.view = QTableView()
      self.view.setModel(model)
      self.view.resizeColumnsToContents()
    
      delegate = genericdelegates.GenericDelegate(self)
      delegate.insertColumnDelegate(CUSTOMER,
        genericdelegates.PlainTextColumnDelegate())
      earliest = QDate.currentDate().addYears(-3)
      delegate.insertColumnDelegate(HIRED,
        HireDateColumnDelegate(earliest))
      delegate.insertColumnDelegate(MILEAGEOUT,
        MileageOutColumnDelegate(0, 1000000))
      delegate.insertColumnDelegate(RETURNED,
        ReturnDateColumnDelegate(earliest))
      delegate.insertColumnDelegate(MILEAGEBACK,
        MileageBackColumnDelegate(0, 1000000))
      delegate.insertColumnDelegate(NOTES,
        genericdelegates.RichTextColumnDelegate())
    
      self.view.setItemDelegate(delegate)
      self.setCentralWidget(self.view)
    
      QShortcut(QKeySequence("Escape"), self, self.close)
      QShortcut(QKeySequence("Ctrl+Q"), self, self.close)
    
      self.setWindowTitle("Car Hire Logs")
    
    
    app = QApplication(sys.argv)
    form = MainForm()
    rect = QApplication.desktop().availableGeometry()
    form.resize(int(rect.width() * 0.7), int(rect.height() * 0.8))
    form.move(0, 0)
    form.show()
    app.exec_()

    运行结果:

    相关推荐:

    python3+PyQt5实现支持多线程的页面索引器应用程序


    以上就是python3+PyQt5泛型委托详解的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:python3+PyQt5 详解 委托
    上一篇:Python写的贪吃蛇游戏例子_python 下一篇:python删除不需要的python文件方法
    Web大前端开发直播班

    相关文章推荐

    • python基础语法详解之函数• 详细讲解Python之Seaborn(数据可视化)• 完全掌握Python数学相关模块• Python详细解析之多线程爬虫与常见搜索算法• 完全掌握Python常用技巧之ip代理

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网