如何更新QDockWidget的子部件,让它在鼠标悬停时自然发生?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (167)

我在QMainWindow中有一个QDockWidget,QDockWidget包含一个QUndoViews堆栈,其中包含我想要在QUndoView中更改文本的命令。可以通过执行Command.setText()来完成这一任务。然而,QUndoView只在我用鼠标悬停在它上面时才显示更新的文本。甚至在setText工作之后都不会立即调用下面的命令:

    self.editor().undoView().setFocus()
    self.editor().undoView().update()
    self.editor().undoView().hide()
    self.editor().undoView().show()

下面是演示问题的最小代码:

from PyQt5.QtWidgets import (QMainWindow, QDockWidget, QPushButton, QLabel, \
                             QStackedWidget, QUndoStack, QUndoCommand, QApplication, \
                             QUndoView)
import sys
from PyQt5.QtCore import QObject, pyqtSignal, Qt

class Command(QUndoCommand):
    def __init__(self):
        super().__init__()

    def undo(self):
        print("Command Undone")

    def redo(self):
        print("Command Redone")


class CommandTimeline(QDockWidget):
    def __init__(self):
        super().__init__()
        self.stackedWidget = QStackedWidget()
        self.setWidget(self.stackedWidget)

    def addUndoView(self, stack):
        view = QUndoView(stack)
        self.stackedWidget.addWidget(view)
        return view


class Obj(QObject):
    nameChanged = pyqtSignal(str)

    def __init__(self, name):
        super().__init__()
        self._name = name

    def setName(self, name):
        self._name = name
        self.nameChanged.emit(name)

    def __str__(self):
        return self._name


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.undoStack = QUndoStack()
        self.commandTimeline = CommandTimeline()
        self.commandTimeline.addUndoView(self.undoStack)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.commandTimeline)
        button = QPushButton("Click")
        self.setCentralWidget(button)
        button.clicked.connect(self.changeObjName)
        self.obj = Obj("A")
        self.addCommand()

    def addCommand(self):
        def getText(obj):
            return "The command text: " + str(obj)
        command = Command()
        command.setText(getText(self.obj))
        self.obj.nameChanged.connect(lambda name: command.setText(getText(self.obj)))
        self.undoStack.push(command)

    def changeObjName(self):
        self.obj.setName("B")


if __name__ == "__main__":
    app = QApplication([])

    window = MainWindow()
    window.show()

    sys.exit(app.exec_())

运行以下代码并注意,单击按钮后,undoview中的文本不会更改,但在停靠在dockwidget上后,文本将立即更新。

如何触发command.setText()?

提问于
用户回答回答于

QUndoCommand如果文本被更改,则不通知,它被设计为具有静态文本。所以我们必须完成这个任务,在这个例子中使用setFocus(),你表示它不工作,但对我来说,它可以工作,所以你可能没有正确地实现它,或者你的MCVE是不可验证的。

import sys

from functools import partial

from PyQt5.QtWidgets import (QMainWindow, QDockWidget, QPushButton, QLabel, \
                             QStackedWidget, QUndoStack, QUndoCommand, QApplication, \
                             QUndoView)
from PyQt5.QtCore import QObject, pyqtSignal, Qt

class Command(QUndoCommand):
    def undo(self):
        print("Command Undone")

    def redo(self):
        print("Command Redone")


class CommandTimeline(QDockWidget):
    def __init__(self):
        super().__init__()
        self.stackedWidget = QStackedWidget()
        self.setWidget(self.stackedWidget)

    def addUndoView(self, stack):
        view = QUndoView(stack)
        self.stackedWidget.addWidget(view)
        return view


class Obj(QObject):
    nameChanged = pyqtSignal(str)

    def __init__(self, name):
        super().__init__()
        self._name = name

    def setName(self, name):
        self._name = name
        self.nameChanged.emit(name)

    def __str__(self):
        return self._name


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.undoStack = QUndoStack()
        self.commandTimeline = CommandTimeline()
        self.view = self.commandTimeline.addUndoView(self.undoStack)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.commandTimeline)
        button = QPushButton("Click")
        self.setCentralWidget(button)
        button.clicked.connect(self.changeObjName)
        self.obj = Obj("A")
        self.addCommand()


    def addCommand(self):
        command = Command()
        command.setText("The command text: {}".format(self.obj))
        self.obj.nameChanged.connect(partial(self.onNameChanged, command))
        self.undoStack.push(command)

    def changeObjName(self):
        self.obj.setName("B")

    def onNameChanged(self, command, name):
        fw = QApplication.focusWidget()
        command.setText("The command text: {}".format(name))
        self.view.setFocus()
        fw.setFocus()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

所属标签

可能回答问题的人

  • 西风

    renzha.net · 站长 (已认证)

    7 粉丝1 提问9 回答
  • 四无君

    0 粉丝0 提问3 回答
  • 旺仔小小鹿

    社区 · 运营 (已认证)

    46 粉丝0 提问2 回答
  • 拉布拉多拉不多

    1 粉丝0 提问2 回答

扫码关注云+社区

领取腾讯云代金券