我试图隐藏未填充行编辑时创建的错误标签(“ *”),然后在填充时消失,但程序不一致。< / p>
一个不起作用的示例:
将三个插槽留空,然后按“添加学生”按钮-每个星号旁边将出现一个红色星号。
在第一行(“开始日期”)中输入任何内容,然后按“添加学生”按钮-红色星号将消失。
重复第2个名字,但红色星号不会消失。
重复2个姓氏,但红色星号也不会消失。
import sys
import datetime
from PyQt5 import QtWidgets as qt, QtGui, QtCore
class AddStudent(qt.QMainWindow):
def __init__(self):
# Set the window to the dimensions of the Screen
super().__init__()
screenSize = qt.QDesktopWidget().screenGeometry(-1)
self.height = screenSize.height()
self.width = screenSize.width()
self.setGeometry(0, 0, self.width, self.height)
self.setStyleSheet("QLabel {font: 16pt}")
# Add the buttons, line edits, and table
self.foundError = False
self.setup()
# Display the GUI
self.setWindowTitle("Add Student")
def setup(self):
self.startingDateLabel()
self.firstNameLabel()
self.lastNameLabel()
self.addStudentButton()
# Button Declarations
def startingDateLabel(self):
self.dateLabel = qt.QLabel(self)
self.dateLabel.setText("Starting Date:")
# (L/R, U/D, L/R, U/D)
self.dateLabel.setGeometry(158, 150, 262, 50)
self.dateLineEdit = qt.QLineEdit(self)
date = str(datetime.date.today()).split("-")
today = date[1] + "/" + date[2] + "/" + date[0]
self.dateLineEdit.setText(today)
self.dateLineEdit.setGeometry(435, 155, 250, 50)
def firstNameLabel(self):
self.firstName = qt.QLabel(self)
self.firstName.setText("First Name:")
self.firstName.setGeometry(205, 250, 215, 50)
self.firstNameLineEdit = qt.QLineEdit(self)
self.firstNameLineEdit.setGeometry(435, 255, 250, 50)
def lastNameLabel(self):
self.lastName = qt.QLabel(self)
self.lastName.setText("Last Name:")
self.lastName.setGeometry(208, 350, 212, 50)
self.lastNameLineEdit = qt.QLineEdit(self)
self.lastNameLineEdit.setGeometry(435, 355, 250, 50)
def addStudentButton(self):
self.addStudent = qt.QPushButton(self)
self.addStudent.setText("Add Student")
self.addStudent.setGeometry(800, 1500, 150, 50)
self.addStudent.clicked.connect(self.addStudentButtonPressed)
self.addStudent.show()
def addStudentButtonPressed(self):
# Check to make sure that everything that needs to be filled out is filled out
self.errorFound = False
# Check the starting date
if (self.dateLineEdit.text() == ""):
self.error1 = qt.QLabel(self)
self.error1.setText("*")
self.error1.setStyleSheet('color: red')
self.error1.setGeometry(715, 155, 30, 50)
self.error1.show()
self.errorFound = True
else:
try:
self.error1.hide()
self.errorFound = False
except:
self.errorFound = False
# Check the first name slot
if (self.firstNameLineEdit.text() == ""):
self.error2 = qt.QLabel(self)
self.error2.setText("*")
self.error2.setStyleSheet('color: red')
self.error2.setGeometry(715, 255, 30, 50)
self.error2.show()
self.errorFound = True
else:
try:
self.error2.hide()
self.errorFound = False
except:
self.errorFound = False
# Check the last name slot
if (self.lastNameLineEdit.text() == ""):
self.error3 = qt.QLabel(self)
self.error3.setText("*")
self.error3.setStyleSheet('color: red')
self.error3.setGeometry(715, 355, 30, 50)
self.error3.show()
self.errorFound = True
else:
try:
self.error3.hide()
self.errorFound = False
except:
self.errorFound = False
# Run the window
app = qt.QApplication(sys.argv)
window = AddStudent()
window.show()
sys.exit(app.exec())
答案 0 :(得分:0)
我对您的代码进行了以下更改:
self.errorFound
的使用。正如我在评论中所暗示的那样,您永远不会在任何地方真正检查此值。如果只想知道任何个用户输入是否错误,最好只使用一个self.errorFound
,但是一个布尔值不能告诉您哪个输入是错误的。错误。我只是在每次调用submit
函数时检查用户输入的文本是否为空。QFormLayout
类将小部件放置在屏幕上。这消除了键入小部件应属于的绝对坐标的所有猜测和数学运算。如果窗口太小,还可以防止小部件“消失”。这具有每行只能容纳两个小部件的限制。因此,我放弃了星号,只为相应的错误输入为QLabel着色。可以使用QGridLayout
解决这个问题,或者,如果您喜欢QFormLayout
,可以在每个字段中嵌套QHBoxLayout
个对象。让我知道是否需要星号。所有这些都没有了,下面是更新的代码:
import sys
import datetime
from PyQt5 import QtWidgets as qt, QtGui, QtCore
class MyApp(qt.QMainWindow):
def __init__(self):
super().__init__()
screenSize = qt.QDesktopWidget().screenGeometry(-1)
self.setup()
self.setWindowTitle("My Awesome App!")
def setup(self):
self.form = qt.QGroupBox("Add Student")
self.form_layout = qt.QFormLayout()
self.create_date_input()
self.create_first_name_input()
self.create_last_name_input()
self.create_submit_button()
self.form.setLayout(self.form_layout)
self.setContentsMargins(5, 5, 5, 5)
self.setCentralWidget(self.form)
def create_date_input(self):
self.date_label = qt.QLabel("Starting Date:")
self.date_entry = qt.QLineEdit(self)
date = str(datetime.date.today()).split("-")
today = date[1] + "/" + date[2] + "/" + date[0]
self.date_entry.setText(today)
self.form_layout.addRow(
self.date_label,
self.date_entry,
)
def create_first_name_input(self):
self.first_name_label = qt.QLabel("First Name:")
self.first_name_entry = qt.QLineEdit(self)
self.form_layout.addRow(
self.first_name_label,
self.first_name_entry,
)
def create_last_name_input(self):
self.last_name_label = qt.QLabel("Last Name:")
self.last_name_entry = qt.QLineEdit(self)
self.form_layout.addRow(
self.last_name_label,
self.last_name_entry,
)
def create_submit_button(self):
self.submit_button = qt.QPushButton(self)
self.submit_button.setText("Add Student")
self.submit_button.clicked.connect(self.submit)
self.form_layout.addRow(self.submit_button)
def submit(self):
default_color = "color: black"
error_color = "color: red"
date_color = default_color
first_name_color = default_color
last_name_color = default_color
#really should validate if this is a date, not just if it is empty
if (self.date_entry.text() == ""):
date_color = error_color
if (self.first_name_entry.text() == ""):
first_name_color = error_color
if (self.last_name_entry.text() == ""):
last_name_color = error_color
self.date_label.setStyleSheet(date_color)
self.first_name_label.setStyleSheet(first_name_color)
self.last_name_label.setStyleSheet(last_name_color)
app = qt.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec())
答案 1 :(得分:0)
这是另一种可能的解决方案;尽管它似乎比CodeSurgeon提出的the other one复杂一些,但在我看来,它可以扩展得多-并且在某种程度上更优雅。
这里的捕获是QLineEdit的子类,该子类嵌入了子QLabel,只有在字段中有文本时,该子类才可见。添加了resizeEvent
替代项,以确保在调整窗口大小时始终始终正确放置“ *”标签。
这种方法有很多优点,但是最重要的是,将“主”窗口小部件子类化,而不是创建一个嵌入其他窗口小部件的新窗口,而是自动公开其所有方法和属性。
因此,所有这些都使您可以根据需要添加任意数量的[文本]字段,并且仅当每个字段中都包含某些内容时,才启用/禁用提交按钮。
import sys
from PyQt5 import QtCore, QtWidgets
class MyLineEdit(QtWidgets.QLineEdit):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# the "invalid" label *has* to be a child of this QLineEdit
self.invalidLabel = QtWidgets.QLabel('*', self)
self.invalidLabel.setStyleSheet('color: red;')
spacing = 2
# get default margins and re-set them accordingly
self.leftMargin, self.topMargin, self.rightMargin, self.bottomMargin = self.getContentsMargins()
self.rightMargin += self.invalidLabel.minimumSizeHint().width() + spacing
self.setContentsMargins(self.leftMargin, self.topMargin, self.rightMargin + spacing, self.bottomMargin)
self.textChanged.connect(self.setValid)
self.setValid(self.text())
def setValid(self, text):
self.invalidLabel.setVisible(not bool(text))
def isValid(self):
return bool(self.text())
def resizeEvent(self, event):
self.invalidLabel.setGeometry(self.width() - self.rightMargin, self.topMargin,
self.invalidLabel.minimumSizeHint().width(), self.height() - self.topMargin - self.bottomMargin)
class MyApp(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setup()
def setup(self):
self.form = QtWidgets.QGroupBox("Add Student")
self.setCentralWidget(self.form)
self.formLayout = QtWidgets.QFormLayout()
self.form.setLayout(self.formLayout)
self.fields = []
self.create_field('Starting Date:', defaultValue=QtCore.QDate.currentDate().toString('MM/dd/yyyy'))
self.create_field('First Name:')
self.create_field('Last Name:')
self.create_submit_button()
def create_field(self, label, defaultValue=''):
field = MyLineEdit(defaultValue)
self.fields.append(field)
field.defaultValue = field.text()
self.formLayout.addRow(label, field)
field.textChanged.connect(self.checkFields)
def create_submit_button(self):
self.submitButton = QtWidgets.QPushButton('Add Student')
self.formLayout.addRow(self.submitButton)
self.submitButton.clicked.connect(self.submit)
self.submitButton.setEnabled(False)
self.checkFields()
def checkFields(self):
self.submitButton.setEnabled(all(field.isValid() for field in self.fields))
def submit(self):
# doSomething([field.text() for field in self.fields)
for field in self.fields:
field.setText(field.defaultValue)
app = QtWidgets.QApplication(sys.argv)
w = MyApp()
w.show()
sys.exit(app.exec_())
正如已经指出的那样,由于正在使用行编辑,因此您应该真正考虑验证日期内容(因为可以在其中输入任何内容)。
更好的解决方案是使用QDateEdit,但是您需要像对QLineEdit一样对它进行子类化,并创建一个单独的create
函数,并且显然,在提交“验证”时,它将被“忽略”为QDateEdit字段自动允许输入有效的日期。
否则,您可以使用QValidator,但这将是a **中的谚语,主要是因为QDateTime已经通过使用setCalendarPopup(True)
提供了验证和良好的日历视图,并且通过正则表达式验证日期确实很烦人。