只允许 Ints 进入 QPlainTextEdit
Posted
技术标签:
【中文标题】只允许 Ints 进入 QPlainTextEdit【英文标题】:Alowing only Int's into QPlainTextEdit 【发布时间】:2018-01-22 06:46:53 【问题描述】:我正在 python 上创建一个 gui,人们可以在其中将一些数据输入到几个 QPlainTextEdit 元素中。我想检查一下,数据是否为整数?如果不是 - 我需要删除所有输入的内容。我试图通过这个来做到这一点:
regexp = QtCore.QRegExp('^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$')
self.Start_i.textChanged.connect(QtGui.QRegExpValidator(regexp))
Start_i
是 QPlainTextEdit 元素之一,在我看来,它应该检查输入数据是 0 到 255 之间的整数。但它不起作用。
好像我需要使用类似的东西:
if not self.Start_i.textChanged.connect(QtGui.QRegExpValidator(regexp))
self.Start_i.setPlainText(old_text[:-1])
但我仍然不知道如何正确地做到这一点。
我也知道有 QIntValidator(),试了一下:
self.Start_i.textChanged.connect(QtGui.QIntValidator(0,65535))
或
validator = QtGui.QIntValidator(0, 100);
self.Start_i.setValidator(validator)
UPD:我这样做了 -
self.Start_i.textChanged.connect(validation)
然后:
def validation():
regexp = QtCore.QRegExp('^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$')
valid=QtGui.QRegExpValidator.validate(regexp)
if not valid:
Ui_IPG_weld.Start_i.setPlainText('0')
但出现错误:
TypeError: validate(self, str, int): first argument of unbound method must have type 'QRegExpValidator'
UPD 2:有我的完整代码:
from PyQt5 import QtGui
import re
import Ipg_weld
from Ipg_weld import Ui_IPG_weld
import Reading
import Writing
class Test(Ui_IPG_weld):
def __init__(self):
super().__init__()
self.widget = QMainWindow()
self.setupUi(self.widget)
# ...
self.Read_Button.clicked.connect(self.read_file)
self.Savebutton.clicked.connect(self.write_file)
#validator = QtGui.QIntValidator(0, 100); #Valid for values between 0 and 100
#self.Start_i.setValidator(validator)
self.Start_i.textChanged.connect(validation)
self.widget.show()
def read_file(self):
file_values = Reading.reading()
print("Got values from Setup_weld.src and Execute_weld.src:", file_values)
# changing values in plainTexts
self.Start_o.setPlainText(file_values[0][0]) #Start
self.Strobe_o.setPlainText(file_values[0][1]) #Strobe
self.Bit0_o.setPlainText(file_values[0][10]) #Bit0
self.Bit1_o.setPlainText(file_values[0][9]) #Bit1
self.Bit2_o.setPlainText(file_values[0][8]) #Bit2
self.Bit3_o.setPlainText(file_values[0][7]) #Bit3
self.Bit4_o.setPlainText(file_values[0][6]) #Bit4
self.Bit5_o.setPlainText(file_values[0][5]) #Bit5
self.Bit6_o.setPlainText(file_values[0][4]) #Bit6
self.Bit7_o.setPlainText(file_values[0][3]) #Bit7
self.Bit8_o.setPlainText(file_values[0][2]) #Bit8
self.Enable_o.setPlainText(file_values[0][11]) #Enable
self.Active_o.setPlainText(file_values[1][3]) #active
self.Ready_o.setPlainText(file_values[1][0]) #ready
self.Error_o.setPlainText(file_values[0][11]) #error
def write_file(self):
#new_values=Writing.writing()
user_input=[]
user_input.clear()
user_input.append(self.Active_i.toPlainText())
user_input.append(self.Ready_i.toPlainText())
user_input.append(self.Error_i.toPlainText())
user_input.append(self.Bit0_i.toPlainText())
user_input.append(self.Bit1_i.toPlainText())
user_input.append(self.Bit2_i.toPlainText())
user_input.append(self.Bit3_i.toPlainText())
user_input.append(self.Bit4_i.toPlainText())
user_input.append(self.Bit5_i.toPlainText())
user_input.append(self.Bit6_i.toPlainText())
user_input.append(self.Bit7_i.toPlainText())
user_input.append(self.Bit8_i.toPlainText())
user_input.append(self.Strobe_i.toPlainText())
user_input.append(self.Start_i.toPlainText())
user_input.append(self.Enable_i.toPlainText())
print(user_input)
def validation():
#regexp = QtCore.QRegExp('^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$')
regexp = re.match('^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$')
valid=QtGui.QRegExpValidator.validate(regexp)
if not valid:
Ui_IPG_weld.Start_i.setPlainText('0')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Test()
sys.exit(app.exec_())
【问题讨论】:
我提出了一个通用解决方案,我怀疑这就是您想要的,您可以通过所需输入和输出的示例更好地解释我。我问这个是因为用户通常一个字母一个字母地写或粘贴,第二个很容易解决,但第一个很难,因为你必须知道什么时候开始写文本。在 QLineEdit 的情况下没有问题,因为所有文本都经过验证,但在您的情况下,它不能直接完成,除非它是逐行的。 我添加了完整的代码以使其更清晰。我试图为我的程序调整你的代码,但没有奏效 我的解决方案不是直接的,但我需要您解释一下,您可以通过示例说明您拥有什么样的输入以及想要获得什么样的输出。我还需要显示 Ui_IPG_weld 代码。 因为在验证 QLineEdit 时会验证整个文本,如果文本无效,则不会更改此文本,但在 QPlainTextEdit 的情况下,不能验证整个文本,但某些字符串,比如用空格分隔的字符串:“123 545” 【参考方案1】:第一种解决方案是实现QPlainText的keyPressEvent方法,如下所示:
class PlainTextEdit(QtWidgets.QPlainTextEdit):
def __init__(self, parent=None):
QtWidgets.QPlainTextEdit.__init__(self, parent)
regexp = QtCore.QRegExp('^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$')
self.validator= QtGui.QRegExpValidator(regexp)
def keyPressEvent(self, event):
state = self.validator.validate(event.text(), 0)
if state[0] == QtGui.QValidator.Acceptable:
QtWidgets.QPlainTextEdit.keyPressEvent(self, event)
但是这种方案的缺点是只有当用户通过键盘输入文本时才会生效,而粘贴一些文本时不会生效。
因此它实现了这个纠正这个错误的新方法:
from PyQt5 import QtCore, QtGui, QtWidgets
class PlainTextEdit(QtWidgets.QPlainTextEdit):
def __init__(self, parent=None):
QtWidgets.QPlainTextEdit.__init__(self, parent)
regexp = QtCore.QRegExp('^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$')
self.validator= QtGui.QRegExpValidator(regexp)
self.document().contentsChange.connect(self.onContentsChange)
def onContentsChange(self, position, charsRemoved, charsAdded):
if charsAdded > 0:
beforeText = self.toPlainText()[:position]
text = self.toPlainText()[position:position+charsAdded]
afterText = self.toPlainText()[position+charsAdded:]
newText = ""
for letter in text:
state, _, _ = self.validator.validate(letter, 0)
if state == QtGui.QValidator.Acceptable:
newText += letter
oldState = self.document().blockSignals(True)
self.setPlainText(beforeText+newText+afterText)
self.document().blockSignals(oldState)
cursor = QtGui.QTextCursor(self.document())
cursor.movePosition(QtGui.QTextCursor.End)
self.setTextCursor(cursor)
如果你想在 Qt Designer 中使用这个类,你必须为此推广它,你必须遵循以下步骤:
-
我认为您应该拥有的项目结构如下:
.
├── Ipg_weld.py
├── main.py <----Main file that you show in your question.
└── your_designer.ui
-
您必须创建一个新的 .py 文件并将我提议的 PlainTextEdit 类放入其中,因此结构如下所示:
.
├── Ipg_weld.py
├── main.py <----Main file that you show in your question.
├── PlainTextEdit.py <-- This file has the PlainTextEdit class.
└── your_designer.ui
-
在 Qt Designer 的帮助下打开 .ui 文件,然后单击要放置验证器的 QPlainTextEdit 按钮,然后选择选项Promote to ...:
-
你会得到一个如下图所示的对话框窗口,在Promoted class name 框中你必须放置PlainTextEdit,在Header File 中你必须放置PlainTextEdit.h,在按下add 和Promote 之后:
-
在 pyuic 的帮助下再次将文件 ui 转换为文件 Ipg_weld.py 后。
上面的PlainTextEdit类将被加载,你只需要运行你的主文件。
【讨论】:
试过了。看起来这有效,但现在当我尝试将任何内容写入 self.Enable_o.setObjectName("Enable_o") self.Enable_i = PlainTextEdit(self.centralWidget) self.Enable_i.setGeometry(QtCore.QRect(620, 520, 41 , 31)) self.Enable_i.setReadOnly(False) self.Enable_i.setPlainText("") 它只是冻结了整个程序 换句话说 - 所有 PlainTextEdit 元素工作正常,但其中一个使整个程序冻结 不知道发生了什么,但好像消失了!甚至不知道发生了什么,但非常感谢您,先生,您的耐心和时间!您的解决方案非常完美!以上是关于只允许 Ints 进入 QPlainTextEdit的主要内容,如果未能解决你的问题,请参考以下文章
只允许我的 android 应用程序在 java 中执行端点 api