我试图让用户在填写表格 1 之前不要切换到“表格 2”所在的下一个选项卡。
我尝试了“currentChange”事件,但它没有按照我想要的方式工作,因为它在已经从 TAB 更改时显示警报。
有没有办法让当前的 TAB 保持固定,直到任务完成?
我附上代码和图像
import sys
from PyQt5.QtCore import Qt
from PyQt5 import QtWidgets
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super(MyWidget, self).__init__()
self.setGeometry(0, 0, 800, 500)
self.setLayout(QtWidgets.QVBoxLayout())
#flag to not show the alert when starting the program
self.flag = True
#changes to True when the form is completed
self.form_completed = False
#WIDGET TAB 1
self.widget_form1 = QtWidgets.QWidget()
self.widget_form1.setLayout(QtWidgets.QVBoxLayout())
self.widget_form1.layout().setAlignment(Qt.AlignHCenter)
label_form1 = QtWidgets.QLabel("FORM 1")
self.widget_form1.layout().addWidget(label_form1)
#WIDGET TAB 2
self.widget_form2 = QtWidgets.QWidget()
self.widget_form2.setLayout(QtWidgets.QVBoxLayout())
self.widget_form2.layout().setAlignment(Qt.AlignHCenter)
label_form2 = QtWidgets.QLabel("FORM 2")
self.widget_form2.layout().addWidget(label_form2)
#QTABWIDGET
self.tab_widget = QtWidgets.QTabWidget()
self.tab_widget.currentChanged.connect(self.changed)
self.tab_widget.addTab(self.widget_form1,"Form 1")
self.tab_widget.addTab(self.widget_form2, "Form 2")
self.layout().addWidget(self.tab_widget)
def changed(self,index):
if self.flag:
self.flag = False
return
if not self.form_completed:
QtWidgets.QMessageBox.about(self, "Warning", "You must complete the form")
return
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mw = MyWidget()
mw.show()
sys.exit(app.exec_())
The currentChanged
当索引已经改变时发出信号(动词是过去时:Changed),所以如果你想prevent更改后,您必须检测任何用户尝试切换选项卡。
为此,您必须检查鼠标和键盘事件:
- 鼠标左键单击选项卡栏;
-
Ctrl+Tab and Ctrl+Shift+Tab on the tab widget;
由于您必须从主窗口控制该行为,唯一的解决方案是在选项卡小部件及其上安装事件过滤器tabBar(),那么如果该操作会更改索引但表单未完成,则必须返回True
这样该事件就不会被小部件处理。
请考虑以下假设必须保持活动的选项卡是current(第一个添加的选项卡,或使用设置的选项卡setCurrentIndex()
).
class MyWidget(QtWidgets.QWidget):
def __init__(self):
# ...
self.tab_widget.installEventFilter(self)
self.tab_widget.tabBar().installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == event.KeyPress and \
event.key() in (Qt.Key_Left, Qt.Key_Right):
return not self.form_completed
elif source == self.tab_widget.tabBar() and \
event.type() == event.MouseButtonPress and \
event.button() == Qt.LeftButton:
tab = self.tab_widget.tabBar().tabAt(event.pos())
if tab >= 0 and tab != self.tab_widget.currentIndex():
return self.isInvalid()
elif source == self.tab_widget and \
event.type() == event.KeyPress and \
event.key() in (Qt.Key_Tab, Qt.Key_Backtab) and \
event.modifiers() & Qt.ControlModifier:
return self.isInvalid()
return super().eventFilter(source, event)
def isInvalid(self):
if not self.form_completed:
QTimer.singleShot(0, lambda: QtWidgets.QMessageBox.about(
self, "Warning", "You must complete the form"))
return True
return False
请注意,我使用 QTimer 显示消息框,以便立即正确返回事件过滤器。
另请考虑,在对象创建和配置结束时连接信号是一种很好的做法,这对于通知属性更改的信号更为重要:在设置可能触发它的属性之前,不应连接它。
由于空的 QTabWidget 有一个-1
索引,一旦添加第一个选项卡,索引就会更改为0
,从而触发信号。只需移动currentChanged
信号连接after添加选项卡,您可以摆脱self.flag
check.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)