gpt4 book ai didi

python - 为什么 `QtGui.QValidator.validate`的返回如此不一致?处理这个问题的可靠方法?

转载 作者:行者123 更新时间:2023-12-01 04:58:53 30 4
gpt4 key购买 nike

我正在尝试开发一个使用 Qt 的应用程序。我试图让应用程序同时使用 PySidePyQt4。除了我的自定义 QtGui.QValidator 类之外,我没有遇到任何重大兼容性问题:

import sys
import os
import re

variant = 'PyQt4'
#variant = 'PySide'

print 'Python {}, {}'.format(sys.version, sys.platform)

# Using PyQt4:
if variant == 'PySide':
import PySide
from PySide import QtGui, QtCore
print 'PySide {}, Qt {}'.format(PySide.__version__, PySide.QtCore.__version__)

# Using PySide:
if variant == 'PyQt4':
from PyQt4 import QtGui, QtCore
from PyQt4.Qt import PYQT_VERSION_STR
print 'PyQt4 {}, Qt {}'.format(PYQT_VERSION_STR, QtCore.QT_VERSION_STR)

class ExpressionValidator(QtGui.QValidator):
def __init__(self, parent=None,):
QtGui.QValidator.__init__(self, parent)

self.states = {'invalid': QtGui.QValidator.Invalid,
'intermediate': QtGui.QValidator.Intermediate,
'acceptable': QtGui.QValidator.Acceptable,
}

self.regX_expression = re.compile('([0-9.eEpiPI+-/*\(\))\^]*)')

def returnState(self, state, text, pos):

if state == 'acceptable':
color = '#00cc00' # green
elif state == 'intermediate':
color = '#fff79a' # yellow
else:
color = '#f6989d' # red
self.parent().setStyleSheet('QLineEdit {{ background-color: {} }}'.format(color))

if variant == 'PySide':
return self.states[state]
else:
return (self.states[state], pos)


def validate(self, textInput, pos):
# Check text, return state
matches = self.regX_expression.findall(textInput)
if matches and len(matches[0]) == len(textInput):
if len(textInput) >0 and str(textInput)[-1] in '+-/*^':
self.parent().setToolTip('Expression Needs Finished.')
return self.returnState('intermediate', textInput, pos)
else:
return self.returnState('acceptable', textInput, pos)
else:
return self.returnState('invalid', textInput, pos)


if __name__ == "__main__":

app = QtGui.QApplication(sys.argv)
app.setStyle('GTK')
mainWindow = QtGui.QMainWindow()

lineEdit = QtGui.QLineEdit()
lineEdit.setValidator(ExpressionValidator(lineEdit))

mainWindow.setCentralWidget(lineEdit)
mainWindow.show()

app.exec_()

app.deleteLater()
sys.exit()

我需要将健壮的代码放置在 returnState 函数中。我是否只需在多个系统上进行测试并继续构建我的 if 语句?

到目前为止,这些调用有效:

  • Python 2.7.6、Windows 7、PyQt4 4.10.4、Qt 4.8.6:

    • return (self.states[state], pos)
  • Python 2.7.6、Windows 7、PySide 1.2.1、Qt 4.8.6:

    • 返回 self.states[状态]

    • return (self.states[state], text, pos)

  • Python 2.7.8、OpenSuse (linux2)、PyQt4 4.10.4、Qt 4.8.5:

    • return (self.states[state], pos)
  • Python 2.7、OpenSuse (linux2)、PyQt4 4.8.3、Qt 4.7.1:

    • return (self.states[state], pos)
  • Python 2.7.8、OpenSuse (linux2)、PySide 1.2.1、Qt 4.8.5:

    • 返回 self.states[状态]

    • return (self.states[state], text, pos)

如何解析 help(QtGui.QValidator.validate) 以获得正确的调用并基于此动态创建返回调用?

最佳答案

更新:

正如 Onlyjus 在评论中指出的那样,确切的行为因which PyQt api而异。正在使用中。

对于 v1 api,input 参数将是一个 QString,这意味着它可以就地修改(这就是 C++ api 的工作方式)。但对于 v2 api,input 参数是一个不可变的 python 字符串,因此必须返回它。所以实际的签名是:

# v1 api (default for Python 2)
QValidator.validate(QString, int) -> (QValidator.State, int)
# v2 api (default for Python 3)
QValidator.validate(str, int) -> (QValidator.State, str, int)

这些(以及许多其他)差异记录在 PyQt4 and Python v3 中PyQt4 文档的部分。

PySide 的行为虽然有点奇怪,但至少是可以预测的。只要前三个值的类型与 C++ 签名相符,它将允许返回任意长度的元组。所以这些都可以:

    return (QValidator.State,)
return (QValidator.State, "string")
return (QValidator.State, "string", 10)
return (QValidator.State, "string", 10, "foo", 60, "blah")

但这种灵 active 在当前情况下没有任何帮助,因为在使用 v1 api 时,PyQt4 无法匹配任何这些变体。

看起来唯一真正的解决方案是切换到 v2 api(至少对于 QString)。

但是,如果您无法做到这一点,最好的折衷方案是使用与您已经在做的事情非常相似的东西:

    if variant == 'PyQt4':
# if necessary, modify text in place here
# rather than returning it
return (self.states[state], pos)
else:
return (self.states[state], text, pos)

这应该适用于 PySide、PyQt4 和 PyQt5(如果您也选择提供支持)。

关于python - 为什么 `QtGui.QValidator.validate`的返回如此不一致?处理这个问题的可靠方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26759623/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com