簡體   English   中英

使用 enterEvent 和 leaveEvent 時 PyQt QStackedWidget 出現遞歸錯誤

[英]Recursion Error on PyQt QStackedWidget when using enterEvent and leaveEvent

我正在使用一個QStackedWidget ,它有自己的enterEventleaveEvent 當我將鼠標移動到QStackedWidget時, enterEvent將當前索引設置為1 ,而在leaveEvent上,它將當前索引設置為0 ,以便在QStackedWidget區域的鼠標進入和鼠標離開時顯示不同的小部件。 僅當我快速將鼠標移入和移出時,它才能執行我想要的操作,如果我將鼠標放置在該區域中的時間過長,則會出現RecursionError: maximum recursion depth exceeded

這是因為小部件變化如此之快以至於內部堆棧無法跟上? 我的問題是“如何確保不會發生此錯誤?只要鼠標在QStackedWidget,我想顯示一個小部件,而當它不是時,我想顯示原始小部件。”

以下是我修改的代碼(原始來源使用按鈕設置索引,它是PyQt4

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

class FaderWidget(QWidget):

    def __init__(self, old_widget, new_widget):
        QWidget.__init__(self, new_widget)
        self.old_pixmap = QPixmap(new_widget.size())
        old_widget.render(self.old_pixmap)
        self.pixmap_opacity = 1.0
        self.timeline = QTimeLine()
        self.timeline.valueChanged.connect(self.animate)
        self.timeline.finished.connect(self.close)
        self.timeline.setDuration(333)
        self.timeline.start()

        self.resize(new_widget.size())
        self.show()


    def animate(self, value):

        self.pixmap_opacity = 1.0 - value
        self.repaint()

class StackedWidget(QStackedWidget):

    def __init__(self, parent = None):
        QStackedWidget.__init__(self, parent)

    def setCurrentIndex(self, index):
        self.fader_widget = FaderWidget(self.currentWidget(), self.widget(index))
        super().setCurrentIndex(index)

    def enterEvent(self,event):
        self.setCurrentIndex(1)

    def leaveEvent(self,event):
        self.setCurrentIndex(0)


if __name__ == "__main__":

    app = QApplication(sys.argv)

    window = QWidget()

    stack = StackedWidget()
    cal=QCalendarWidget()
    stack.addWidget(cal)
    editor = QTextEdit()
    editor.setPlainText("Hello world! "*100)
    stack.addWidget(editor)

    layout = QGridLayout(window)
    layout.addWidget(stack, 0, 0, 1, 2)

    window.show()
    sys.exit(app.exec_())

發生遞歸是因為當您啟動 FaderWidget 時,它會更改焦點並再次調用 enterEvent,從而創建一個新的 FaderWidget。

解決方法是驗證舊索引與新索引不同,只創建FadeWidget:

import sys

from PyQt5.QtCore import QTimeLine
from PyQt5.QtGui import QPainter, QPixmap
from PyQt5.QtWidgets import (
    QApplication,
    QCalendarWidget,
    QGridLayout,
    QStackedWidget,
    QTextEdit,
    QWidget,
)


class FaderWidget(QWidget):
    def __init__(self, old_widget, new_widget):
        QWidget.__init__(self, new_widget)
        self.pixmap_opacity = 1.0
        self.old_pixmap = QPixmap(new_widget.size())
        old_widget.render(self.old_pixmap)

        self.timeline = QTimeLine()
        self.timeline.valueChanged.connect(self.animate)
        self.timeline.finished.connect(self.close)
        self.timeline.setDuration(333)
        self.timeline.start()

        self.resize(new_widget.size())
        self.show()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setOpacity(self.pixmap_opacity)
        painter.drawPixmap(0, 0, self.old_pixmap)

    def animate(self, value):
        self.pixmap_opacity = 1.0 - value
        self.update()


class StackedWidget(QStackedWidget):
    def setCurrentIndex(self, index):
        if self.currentIndex() != index:
            self.fader_widget = FaderWidget(self.currentWidget(), self.widget(index))
        super().setCurrentIndex(index)

    def enterEvent(self, event):
        self.setCurrentIndex(1)

    def leaveEvent(self, event):
        self.setCurrentIndex(0)


if __name__ == "__main__":

    app = QApplication(sys.argv)

    window = QWidget()

    stack = StackedWidget()
    cal = QCalendarWidget()
    stack.addWidget(cal)
    editor = QTextEdit()
    editor.setPlainText("Hello world! " * 100)
    stack.addWidget(editor)

    layout = QGridLayout(window)
    layout.addWidget(stack, 0, 0, 1, 2)

    window.show()
    sys.exit(app.exec_())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM