在PyQt5中3秒后自动更改Stacked Widget索引

时间:2018-09-20 14:23:26

标签: python pyqt5

我试图显示堆叠式小部件的第一页(欢迎页面),并在3秒钟后自动将其替换为第二页(“菜单”页面)。

我尝试了这种方法,但是没有用。

..........

self.stackedWidget.setCurrentIndex(0)
time.sleep(3) 
self.stackedWidget.setCurrentIndex(1) 
QtCore.QMetaObject.connectSlotsByName(smartUpdaterUI)

..............

2 个答案:

答案 0 :(得分:1)

Qt使用GUI事件循环来处理事件并更新UI。在将控制权移交给事件循环并拾取并处理该更新之前,将看不到GUI的任何更新。

您使用Python编写的代码与GUI发生在同一线程中。因此,在代码运行时,事件循环不会运行,更改也不会得到处理。

侧面说明:这就是为什么如果您尝试执行长时间运行的操作(例如访问API)而不使用单独的线程,则应用程序会“挂起”的原因。

在代码中,您将当前索引设置为0,然后使用Python time.sleep()等待,直到更新为索引1

self.stackedWidget.setCurrentIndex(0)
time.sleep(3) # no event loop running here
self.stackedWidget.setCurrentIndex(1) 

发生time.sleep(3)时,此时将保留执行。这意味着控制权不会交还给Qt事件循环,并且第一个更改未得到处理。超时完成后,将设置第二个索引,只有 then 函数才能将控制权返回给Qt。

现在,事件循环会同时应用这两项更改,但立即又一次应用。因此,您所看到的只是将索引设置为1,而无需先显示0且没有任何延迟。

为避免这种情况,您需要在设置初始索引后将控制权返回到事件循环。最简单的方法是先进行设置,然后使用异步QTimer触发后续更新。

self.stackedWidget.setCurrentIndex(0)
QTimer.singleShot(3000, lambda: self.stackedWidget.setCurrentIndex(1))

lambda:用作匿名函数,因此我们可以通过延迟执行直到触发计时器来将1传递给setCurrentIndex。如果您只跳转到单个页面,则可以执行以下操作:

def go_to_page_1(self):
    self.stackedWidget.setCurrentIndex(1)

self.stackedWidget.setCurrentIndex(0)
QTimer.singleShot(3000, go_to_page_1)

答案 1 :(得分:0)

  

void QTimer :: singleShot(int msec,const QObject * receiver,const char * member)

     

此静态函数在给定的时间间隔后调用一个插槽。

尝试一下:

import sys
from PyQt5.QtCore    import *
from PyQt5.QtGui     import *
from PyQt5.QtWidgets import *

class stackedExample(QWidget):
    def __init__(self):
        super(stackedExample, self).__init__()

        self.leftlist = QListWidget()
        self.leftlist.insertItem (0, 'Contact'     )
        self.leftlist.insertItem (1, 'Personal'    )
        self.leftlist.insertItem (2, 'Educational' )

        self.stack1 = QWidget()
        self.stack2 = QWidget()
        self.stack3 = QWidget()

        self.stack1UI()
        self.stack2UI()
        self.stack3UI()

        self.stackWidget = QStackedWidget(self)
        self.stackWidget.addWidget(self.stack1)
        self.stackWidget.addWidget(self.stack2)
        self.stackWidget.addWidget(self.stack3)

        hbox = QHBoxLayout(self)
        hbox.addWidget(self.leftlist)
        hbox.addWidget(self.stackWidget)

        self.setLayout(hbox)
        self.leftlist.currentRowChanged.connect(self.display)
        self.setGeometry(300, 50, 10, 10)
        self.setWindowTitle('StackedWidget demo')

        self.stackWidget.setCurrentIndex(0)
        QTimer.singleShot(3000, lambda: self.display(1))
        QTimer.singleShot(6000, lambda: self.display(2))
        QTimer.singleShot(9000, lambda: self.display(0))

        self.show()

    def stack1UI(self):
        layout = QFormLayout()
        layout.addRow("Name",    QLineEdit())
        layout.addRow("Address", QLineEdit())
        #self.setTabText(0,"Contact Details")
        self.stack1.setLayout(layout)

    def stack2UI(self):
        layout = QFormLayout()
        sex    = QHBoxLayout()
        sex.addWidget(QRadioButton("Male"))
        sex.addWidget(QRadioButton("Female"))
        layout.addRow(QLabel("Sex"),sex)
        layout.addRow("Date of Birth",QLineEdit())
        self.stack2.setLayout(layout)

    def stack3UI(self):
        layout = QHBoxLayout()
        layout.addWidget(QLabel("subjects"))
        layout.addWidget(QCheckBox("Physics"))
        layout.addWidget(QCheckBox("Maths"))
        self.stack3.setLayout(layout)

    def display(self, i):
        self.stackWidget.setCurrentIndex(i)

def main():
    app = QApplication(sys.argv)
    ex  = stackedExample()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()