RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1180419
Accepted
Maxim Timakov
Maxim Timakov
Asked:2020-09-21 02:15:22 +0000 UTC2020-09-21 02:15:22 +0000 UTC 2020-09-21 02:15:22 +0000 UTC

Qt5。如何暂时禁用子小部件的事件生成?

  • 772

我正在编写参数编辑器小部件,从子小部件生成事件时出现问题。

小部件本身订阅子小部件的更改并转发上面的事件。
假设编辑器包含一对QLineEdit:

class Editor(QWidget):
    paramsChanged = Signal(str, str)
    
    def __init__(self, parent= None):
        super().__init__(parent)
        self.__build_ui()
    
    def __build_ui(self):
        self.__a = QLineEdit()
        self.__b = QLineEdit();
        
        box = QVBoxLayout()
        
        box.addWidget(self.__a)
        box.addWidget(self.__b)
        self.__a.textChanged.connect(self.__on_paramChanged)
        self.__b.textChanged.connect(self.__on_paramChanged)
        
        self.setLayout(box)
        
    def __on_paramChanged(self):
        self.paramsChanged.emit(self.__a.text(), self.__b.text())
    
    def setParams(self, a, b):
        self.__a.setText(a)
        self.__b.setText(b)

当以编程方式设置值时,子小部件会生成“更改”事件。

editor.setParams("a", "b")

日志:

changed a 
changed a b

实际上问题是:如何
在加载参数()期间Editor::setParams禁用子小部件的事件生成?

完整的代码Python + PySide2

# -*- coding: utf-8 -*-
import sys

from PySide2.QtCore import *
from PySide2.QtWidgets import *


class Editor(QWidget):
    paramsChanged = Signal(str, str)

    def __init__(self, parent= None):
        super().__init__(parent)
        self.__build_ui()

    def __build_ui(self):
        self.__a = QLineEdit()
        self.__b = QLineEdit();

        box = QVBoxLayout()

        box.addWidget(self.__a)
        box.addWidget(self.__b)
        self.__a.textChanged.connect(self.__on_paramChanged)
        self.__b.textChanged.connect(self.__on_paramChanged)

        self.setLayout(box)

    def __on_paramChanged(self):
        self.paramsChanged.emit(self.__a.text(), self.__b.text())

    def setParams(self, a, b):
        self.__a.setText(a)
        self.__b.setText(b)


def on_change(a, b):
    print("changed", a, b)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    editor = Editor()
    editor.paramsChanged.connect(on_change)

    editor.show()

    editor.setParams("a", "b")

    sys.exit(app.exec_())
qt
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Alexander Chernin
    2020-09-21T04:46:29Z2020-09-21T04:46:29Z

    阻止来自 QObject 后代(包括小部件)的信号:

    QObject.blockSignals(True)
    

    分别解除封锁:

    QObject.blockSignals(False)
    
    • 3
  2. Maxim Timakov
    2020-09-26T00:46:10Z2020-09-26T00:46:10Z

    除了亚历山大·切尔宁的回答

    如果在应用锁时锁已经处于活动状态,则调用 object->blockSignals(false);将释放它,这可能会破坏调用代码。

    例如:

    // Наш класс
    class MyObject: public QObject
    {
    Q_OBJECT
    public:
        void setValues(/* */);
        // ...
    signals:
        void valueChanged();
        // ...
    };
    
    void MyObject::setValues(/* */)
    {
        blockSignals(true);
        // ...
        // какой то код для установки значения в дочерние объекты
        // ...
        blockSignals(false); // безусловная разблокировка
    
        emit valueCanged(); // генерация сигнала
    }
    

    调用代码

    constructor()
    {
        object = new MyObject(this);
        connect(object, ...);
    }
    
    void updateObject()
    {
        object->blockSignals(true);
        // ...
        object->setValues(...);
        // < тут сигналы от object уже разблокированы
        // ...
        object->blockSignals(false);
    }
    

    QObject::blockSignals返回给定对象的前一个信号阻塞状态,允许恢复前一个状态。

    也就是需要修改方法的MyObject::setValues代码updateObject:

    void MyObject::setValues(/* */)
    {
        auto state = blockSignals(true); // сохранение старого состояния
        // ...
        // какой то код для установки значения в дочерние объекты
        // ...
        blockSignals(state); // восстановить состояние блокировки
    
        emit valueCanged(); // генерация сигнала
    }
    
    void updateObject()
    {
        auto state = object->blockSignals(true);
        // ...
        object->setValues(...);
        // OK: сигналы от object еще заблокированы
        // ...
        object->blockSignals(state);
    }
    

    为了不忘记这一点,您可以使用辅助类QSignalBlocker。
    它的算法和使用方法让人想起lock guard

    void updateObject()
    {
        QSignalBlocker block(object); // блокировка
        // ...
        object->setValues(...);
        // ...
        // автоматическое восстановление состояния блокировки
    }
    

    示例Python

    def updateObject(self):
        _ = QSignalBlocker(self.object);
    
        self.object.setValues(...)
    
    • 1

相关问题

  • 在 Windows 7 上将文件连接到 Qt 项目时出现问题

  • QGraphicsView - Qt5 - MouseMoveEvent 没有触发?

  • 如何在背景中添加屏幕保护程序

  • 如何更改包含的 .ttf 字体的大小

  • QString("%1").arg(number + 1) 以 %03d 格式打印数字

  • QT Creator,信号和插槽 [关闭]

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5