【问题标题】:pyqt convert enum value to keypyqt 将枚举值转换为键
【发布时间】:2012-11-12 02:12:09
【问题描述】:

是否可以将 qt 枚举值转换为其键?

例如,我想从 QPrinter 类中获取“A4”,知道 QPrinter.A4 = 0

提前谢谢你

【问题讨论】:

    标签: python qt pyqt pyqt4


    【解决方案1】:

    通常,您可以使用QMetaObject

    m = QtGui.QFrame.staticMetaObject
    m.enumerator(m.indexOfEnumerator('Shadow')).valueToKey(QtGui.QFrame.Sunken)
    'Sunken'
    

    然而,QPrinter 似乎没有暴露元对象,所以你必须通过在 Python 中遍历QPrinter 的属性来做到这一点(幸运的是,PyQt 枚举是int 的子类,所以可以由isinstance识别):

    page_sizes = dict((n, x) for x, n in vars(QtGui.QPrinter).items() if
                      isinstance(n, QtGui.QPrinter.PageSize))
    page_sizes[QtGui.QPrinter.A4]
    'A4'
    

    【讨论】:

      【解决方案2】:

      使用varsisinstance 构建枚举的双向映射:

      >>> from PyQt4.QtGui import QPrinter
      >>> pagesizes = {}
      >>> for key, value in vars(QPrinter).iteritems():
      ...     if isinstance(value, QPrinter.PageSize):
      ...         pagesizes[key] = value
      ...         pagesizes[value] = key
      ... 
      >>> pagesizes['A4']
      0
      >>> pagesizes[QPrinter.A4]
      'A4'
      >>> pagesizes[0]
      'A4'
      

      更新:

      vars() 似乎不适用于所有版本的 PyQt,但 dir() 可能可以。因此,更强大的解决方案可能是:

      >>> pagesizes = {}
      >>> for key in dir(QPrinter):
      ...     value = getattr(QPrinter, key)
      ...     if isinstance(value, QPrinter.PageSize):
      ...         pagesizes[key] = value
      ...         pagesizes[value] = key
      ... 
      

      (注意:仅使用 pyqt-4.10.3/qt-4.8.5pyqt-4.10/qt-5.1.1pyqt- 进行测试5.1/qt-5.1.1)

      【讨论】:

      • 此答案在 PyQt5 和 Python3 中不起作用,即使您将 Python3 的 iteritems() 更改为 items()。纸张尺寸的枚举显然不再属于 QPrinter 类了?
      • Qt5.1 有 QPrinterInfo.supportedSizesWithNames() 但在 Qt5.0.1 中有什么解决方案?
      • @bootchk。这似乎是 PyQt5 中的一个错误:所有其他 QPrinter 枚举和它们的枚举数都显示在 vars() 中——现在只有 PageSize 丢失了。如果枚举键不在 QPrinter 的 __dict__ 中,我认为没有其他方法可以生成枚举键(Qt 的元对象系统在这里也没有帮助,因为 QPrinter 不是 QObject)。
      • @bootchk。如果您仍然感兴趣,我想我可能已经找到了解决方法:请查看我的更新答案。
      【解决方案3】:

      我根据 ecatmur 的回答实现了一个功能:

      def qenum_key(base, value):
          """Convert a Qt Enum value to its key as a string.
      
          Args:
              base: The object the enum is in, e.g. QFrame.
              value: The value to get.
      
          Return:
              The key associated with the value as a string, or None.
          """
          klass = value.__class__
          try:
              idx = klass.staticMetaObject.indexOfEnumerator(klass.__name__)
          except AttributeError:
              idx = -1
          if idx != -1:
              return klass.staticMetaObject.enumerator(idx).valueToKey(value)
          else:
              for name, obj in vars(base).items():
                  if isinstance(obj, klass) and obj == value:
                      return name
              return None
      

      这首先尝试通过 QMetaObject 获取值,如果失败或不存在元对象,则使用纯 Python 方法。

      【讨论】:

        【解决方案4】:

        这个实现类似于The Compiler's one,但找出基类(QPrinter, QFrame 等)本身。

        import sys
        
        
        def enum_key(enum_val, with_val=False):
            """
            Return name of Qt enum value.
            `enum_val` - enum value
            `with_val` (bool) - return value as part of name
            """
            enum_cls = enum_val.__class__
            parent = sys.modules.get(enum_cls.__module__)
            for i in enum_cls.__qualname__.split(".")[:-1]:
                parent = getattr(parent, i)
            m = getattr(parent, "staticMetaObject", None)
            if m:
                idx = m.indexOfEnumerator(enum_cls.__name__)
                name = m.enumerator(idx).valueToKey(enum_val)
            else:
                for n, val in vars(parent).items():
                    if isinstance(val, enum_cls) and val == enum_val:
                        name = n
                        break
            return "%s (%d)" % (name, enum_val) if with_val else name
        
        # from PyQt5 import QtPrintSupport
        # print(enum_key(QtPrintSupport.QPrinter.A5, with_val=1))
        # >> A5 (9)
        

        【讨论】:

          猜你喜欢
          • 2020-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-21
          • 2021-01-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多