精华内容
下载资源
问答
  • 断开信号槽方法disconnect bool QObject::disconnect(const QObject * sender, const char * signal, const QObject * receiver, const char * method) disconnect将断开sender和receiver,成功返回true 断开所有...

    1. 阻塞方法blockSignals

    bool QObject::blockSignals(bool block)

    • 阻塞模式下,这个对象发送的信号都会被阻塞,解除阻塞后则不再阻塞。返回值为之前状态的阻塞情况。
    • 如果block为true,阻塞信号,或者如果block为false,取消信号阻塞。
    ui->deviceComboBox->blockSignals(true);
    ...
    ui->deviceComboBox->addItem(description);
    ui->deviceComboBox->blockSignals(false);
    

    2. 断开信号槽方法disconnect

    bool QObject::disconnect(const QObject * sender, const char * signal, const QObject * receiver, const char * method)
    disconnect将断开sender和receiver,成功返回true

    • 断开所有连接到某一对象的信号槽:(这个和阻塞的功能类似)
    disconnect(myObject, 0, 0, 0); 
    //等价于:
    myObject->disconnect();
    
    • 断开所有连接到某一信号的信号槽:
    disconnect(myObject, SIGNAL(mySignal()), 0, 0);
    // 等价于:
    myObject->disconnect(SIGNAL(mySignal()));
    
    • 断开两个对象之间的所有信号槽关系:
    disconnect(myObject, 0, myReceiver, 0);
    // 等价于:
    myObject->disconnect(myReceiver);
    

    3.结合实例

    (1)QComboBox对象若已连接了当前项发生改变currentIndexChanged(int)时响应信号槽,则对QComboBox对象进行添加或删除项时会触发currentIndexChanged(int)信号。

    • 方法一
    //在调用QComboBox::addItem函数之前先将此信号槽连接断开:
    QObject::disconnect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboBoxSlot()));
    ui.comboBox->addItem(tr("Gaussian filtering"), 1);
    //在添加完成后再调用connect进行连接:
    QObject::connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboBoxSlot()));
    
    • 方法二
    //阻塞信号
    ui->comboBox->blockSignals(true);
    
    ui.comboBox->addItem(tr("Gaussian filtering"), 1);
    //取消信号阻塞
    ui->comboBox->blockSignals(false);
    

    (2)QSlider和QSpinBox同时作用。当滑条滑动时,计数器同时更新显示数据;当计数器输入新的值时,滑条同时自动滑动到新值的位置;无论是滑条还是计数器,改变值都响应相同函数。

    connect(lowSlider, SIGNAL(valueChanged(int)), this, SLOT(lowThresholdValueChanged()));
    connect(lowSlider, SIGNAL(valueChanged(int)), lowSpinBox, SLOT(setValue(int)));
    connect(lowSpinBox, SIGNAL(valueChanged(int)), lowSlider, SLOT(setValue(int)));
    
    void GraspEdge::lowThresholdValueChanged()
    {
    	if (lowSlider->value() > highSlider->value())
    	{
    		disconnect(lowSlider, SIGNAL(valueChanged(int)), lowSpinBox, SLOT(setValue(int)));
    		disconnect(lowSpinBox, SIGNAL(valueChanged(int)), lowSlider, SLOT(setValue(int)));
    		lowSlider->blockSignals(true);
    		lowSpinBox->blockSignals(true);
    
    		lowSlider->setValue(highSlider->value());
    		lowSpinBox->setValue(highSlider->value());
    
    		lowSlider->blockSignals(false);
    		lowSpinBox->blockSignals(false);
    		
    		connect(lowSlider, SIGNAL(valueChanged(int)), lowSpinBox, SLOT(setValue(int)));
    		connect(lowSpinBox, SIGNAL(valueChanged(int)), lowSlider, SLOT(setValue(int)));
    	}
    }
    
    
    展开全文
  • connect用于连接信号和槽函数,但是我们经常忽略最后一个参数,本人在写代码时遇到了bug,选择一个符号进行多次标绘,再选择其他符号时,会...disconnect() 等同于disconnect(this, 0, 0, 0), 删除this的信号与任何槽的

    connect

    connect用于连接信号和槽函数,但是我们经常忽略最后一个参数,本人在写代码时遇到了bug,选择一个符号进行多次标绘,再选择其他符号时,会将上一次选择的符号也进行标绘,主要时connect最后一个参数搞的鬼。

    当conncet最后一个参数不写时,connect多少次,槽函数就执行多少次,本人遇到的bug需要将最后一个参数设为Qt::UniqueConnection,避免多次连接,只连接一次。

    Qt::AutoConnection: 自动。一般不写就默认是这个,使用这个值会根据实际情况去判断,如果sender和receiver在同一个线程,则自动使用Qt::DirectConnection,如果不在一个线程,则自动使用Qt::QueuedConnection。
    Qt::DirectConnection:直连。槽函数会在信号发送的时候直接被调用,槽函数运行于信号发送者所在线程。效果看上去就像是直接在信号发送位置调用了槽函数。这个在多线程环境下比较危险,可能会造成奔溃。
    Qt::QueuedConnection:队列连接。槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。
    Qt::BlockingQueuedConnection:阻塞队列连接。槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。
    Qt::UniqueConnection:唯一连接。这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。

    diconnect

    disconnect(myObject, nullptr, nullptr, nullptr)等同于myObject->disconnect();, 断开myObject的所有信号与任何槽的关联;
    disconnect(myObject, SIGNAL(mySignal()), nullptr, nullptr) 等同于myObject>disconnect(SIGNAL(mySignal()));断开myObject得mySignal信号与任何槽的关联;
    disconnect(myObject, nullptr, myReceiver, nullptr);等同于myObject->disconnect(myReceiver);断开信号发送者myObject和信号接收者myReceiver之间的关联;
    QObject::disconnect(lineEdit, &QLineEdit::textChanged, label, &QLabel::setText);断开特定信号发送者和接收者之间的关联

    其中conncet必须与disconnect成对出现,不然,disconncet之后就连接不上信号

    信号槽实现原理

    1、信号与槽的实现是借助了Qt 的元对象系统,元对象系统有一个元对象编译器,程序编译之前会有一个预处理过程,预处理将一个类/对象中的信号,槽的字符串值分别保存在一个容器中,可能是字符串或者其他的有序容器。

    2、现在有两个容器,比如string_sig,保存了所有的信号的字符串值;string_slot保存了所有的槽函数的字符窜值。

    3、每次调用connect()函数建立信号与槽的连接,就是将给定信号与给定的接收方及其槽函数存储在发送方对象的映射容器中,比如multimap,建立起信号与槽的一一对应关系。

    4、发射信号其实就是调用信号函数(信号就是一种函数),根据该信号的索引在multimap中找到对应的槽函数,在调用槽函数即可。

    5、信号与槽的本质就是函数的调用。

    例子:

    #include <map>
    #include<iostream>
    # define slot
    # define siginal protected
    # define emit
    using namespace std;
    class Object;
    
    struct MetaObject//元对象 每个Object有一个,保存自己拥有的信号和槽函数
    {
    	const char* sig_names;
    	const char* slts_names;
    	static void active(Object* sender, int idx);
    };
    
    struct Connection//保存接收方及其序号
    {
    	Object* receiver;
    	int method;
    };
    
    typedef std::multimap<int, Connection> ConnectionMap;
    //<信号,接收方>每个Object有一个,保存自己的信号发出时需要通知的接收方。每个信号的接收方可能不止一个,用multimap
    typedef std::multimap<int, Connection>::iterator ConnectionMapIt;
    
    static int find_string(const char* str, const char* substr)
    {
    	if (strlen(str) < strlen(substr))
    		return -1;
    	int idx = 0;
    	int len = strlen(substr);
    	bool start = true;
    	const char* pos = str;
    	while (*pos)
    	{
    		if (start && !strncmp(pos, substr, len) && pos[len] == '\n')
    			return idx;
    		start = false;
    		if (*pos == '\n')
    		{
    			idx++;
    			start = true;
    		}
    		pos++;
    	}
    	return -1;
    }
    
    class Object
    {
    	friend class MetaObject;
    public:
    	Object() {};
    	virtual ~Object() {};
    	static void connect(Object* sender, const char* sig, Object* receiver, const char* slt);
    	void testSignal() { emit sig1(); }//测试函数
    
    siginal:
    	void sig1() //信号
    	{
    		cout << "信号发出" << endl;
    		MetaObject::active(this, 0);
    	}
    
    	public slot:
    	void slot1() { cout << "槽函数执行" << endl; }//槽函数
    
    private:
    	static MetaObject meta;//保存自己拥有的信号和槽函数
    	ConnectionMap connections;//multimap<int, Connection>,
    	void metacall(int idx);//根据key去查询对应的槽函数
    };
    
    static const char sig_names[] = "sig1\n";//保存对象中所有信号的字符串的容器
    static const char slts_names[] = "slot1\n";//保存对象中所有槽函数字符串的容器
    MetaObject Object::meta = { sig_names, slts_names };//初始化元对象
    
    void Object::metacall(int idx)//根据key去查询对应的槽函数
    {
    	switch (idx)
    	{
    	case 0:
    		slot1();
    		break;
    	default:
    		break;
    	};
    }
    
    void Object::connect(Object* sender, const char* sig, Object* receiver, const char* slt)//静态成员函数  connect建立信号与槽的连接
    {
    	int sig_idx = find_string(sender->meta.sig_names, sig);//查询有没有这个信号和槽函数
    	int slt_idx = find_string(receiver->meta.slts_names, slt);
    	if (sig_idx == -1 || slt_idx == -1)
    	{
    		perror("signal or slot not found!");
    	}
    	else //添加
    	{
    		Connection c = { receiver, slt_idx };//保存接收方及其槽函数id
    		sender->connections.insert(std::pair<int, Connection>(sig_idx, c));//发送方保存接收方信息
    	}
    }
    
    void MetaObject::active(Object* sender, int idx)//信号发出,根据发出者找出它的接收方
    {
    	ConnectionMapIt it;
    	std::pair<ConnectionMapIt, ConnectionMapIt> ret;
    	ret = sender->connections.equal_range(idx);//equal_range主要是找在multimap中的key相等的value,也是一个迭代器
    	for (it = ret.first; it != ret.second; ++it)
    	{
    		Connection c = (*it).second;//获取之前保存的接受方消息
    		c.receiver->metacall(c.method);//接收方执行之前绑定的槽函数
    	}
    }
    
    int main()
    {
    	Object obj1, obj2;
    	Object::connect(&obj1, "sig1", &obj2, "slot1");//连接信号
    	obj1.testSignal();
    	system("pause");
    	return 0;
    }
    
    展开全文
  • QT中语法说明

    2019-12-24 11:28:25
    一、QtQ_OBJECT的作用 QObject是所有Qt对象的基类。 QObject是Qt模块的核心。它的最主要特征是关于对象间无缝通信的机制:信号与槽。使用connect()建立信号到槽的连接,使用disconnect()销毁连接,使用...

    一、Qt 类中Q_OBJECT的作用

    QObject 是所有Qt对象的基类。

    QObject 是Qt模块的核心。它的最主要特征是关于对象间无缝通信的机制:信号与槽。使用connect()建立信号到槽的连接,使用disconnect()销毁连接,使用blockSignals()暂时阻塞信号以避免无限通知循环,使用connectNotify()和disconnectNotify()追踪连接。

    宏Q_OBJECT是任何实现信号、槽或属性的强制性要求。不管是否需要实现这些机制,都要求使用这个宏。否则会引发一些函数的奇怪行为。

    二、加入q_object编译不过问题解决

    如果一个项目开始没有用Q_OBJECT,后来因为业务需求加入Q_OBJECT,在该类头文件中加了#include<QObject>,再让该类继承QObject,加上Q_OBJECT宏来支持信号与槽,这样会出现各种莫名其妙的错误

    class  TOPIScanningLine : public QGraphicsItem,public QObject
    {
        Q_OBJECT
    }

     

     

    尝试着把Q_OBJECT宏给删掉

    然后编译通过了,但是这样就不能使用信号与槽机制

    解决方法:

    QObject继承要写在第一个,不然Q_OBJECT就不起作用,所以将继承放在第一位,例如

    class  TOPIScanningLine :public QObject, public QGraphicsItem
    {
        Q_OBJECT
    }

     这样就能成功编译。

    三、emit的使用

    假设现在定义了一个类A,现在想在A的一个函数void A::function1()当中的结尾处emit一个信号signal1(),然后利用这个信号触发另一个类B进行某项操作void B::function2(),connect应该如何书写

    比如在一个QMainwindow中,包含类A,B的头文件,是的类A,和类B可见,定义一个类A *a,和一个类B *b,(要分配空间)。就可以这么connect他们。
    connect(a,SIGNAL(signal1()),b,SLOT(function2())); 
    对于A,B两个类出来都必须继承于QObject类。

     

    代码:

    //类A头文件  要有Signals
    signals://鼠标移动信号
        void  mouseMoveSignal(); //鼠标移动
    
    //类A   某函数释放信号
    void TOPIScanningLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        emit  mouseMoveSignal();//释放信号
        QGraphicsItem::mouseMoveEvent(event);
    }
    
    //类B头文件   需要有槽函数
    public slots://槽函数
        void GetDistanceUp();//更新上图距离
    
    //类B  函数链接
    TOPIPic_Up = new TOPIScanningLine();//一定要实例化
    connect(TOPIPic_Up, SIGNAL(mouseMoveSignal()), this, SLOT(GetDistanceUp()));

     四、QT绘制直线、矩形、圆

    1.添加头文件

    #include <QPainter>

    2.重写paintEvent函数,代码如下:

    void MainWindow::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        painter.setPen(QPen(Qt::blue,2));//设置画笔形式
        painter.drawLine(20,20,220,220);//画直线
        painter.drawLine(20,220,220,20);
        painter.drawEllipse(20,20,200,200);//画圆
        painter.drawRect(20,20,200,200);//画矩形
    }

    3.函数需要在头文件中声明

    protected:
        void paintEvent(QPaintEvent *);

     

    展开全文
  • 一、QtQ_OBJECT的作用 QObject是所有Qt对象的基类。 QObject是Qt模块的核心。它的最主要特征是关于对象间无缝通信的机制:信号与槽。使用connect()建立信号到槽的连接,使用disconnect()销毁连接,使用...

    一、Qt 类中Q_OBJECT的作用

    QObject 是所有Qt对象的基类。

    QObject 是Qt模块的核心。它的最主要特征是关于对象间无缝通信的机制:信号与槽。使用connect()建立信号到槽的连接,使用disconnect()销毁连接,使用blockSignals()暂时阻塞信号以避免无限通知循环,使用connectNotify()和disconnectNotify()追踪连接。

    宏Q_OBJECT是任何实现信号、槽或属性的强制性要求。不管是否需要实现这些机制,都要求使用这个宏。否则会引发一些函数的奇怪行为。

    二、加入q_object编译不过问题解决

    如果一个项目开始没有用Q_OBJECT,后来因为业务需求加入Q_OBJECT,在该类头文件中加了#include<QObject>,再让该类继承QObject,加上Q_OBJECT宏来支持信号与槽,这样会出现各种莫名其妙的错误
    class  TOPIScanningLine : public QGraphicsItem,public QObject
    {
        Q_OBJECT
    }

     

     

    尝试着把Q_OBJECT宏给删掉
    然后编译通过了,但是这样就不能使用信号与槽机制
    解决方法:
    QObject继承要写在第一个,不然Q_OBJECT就不起作用,所以将继承放在第一位,例如
    class  TOPIScanningLine :public QObject, public QGraphicsItem
    {
        Q_OBJECT
    }

     这样就能成功编译。

    三、emit的使用

    假设现在定义了一个类A,现在想在A的一个函数void A::function1()当中的结尾处emit一个信号signal1(),然后利用这个信号触发另一个类B进行某项操作void B::function2(),connect应该如何书写

     

    比如在一个QMainwindow中,包含类A,B的头文件,是的类A,和类B可见,定义一个类A *a,和一个类B *b,(要分配空间)。就可以这么connect他们。
    connect(a,SIGNAL(signal1()),b,SLOT(function2())); 
    对于A,B两个类出来都必须继承于QObject类。

     

    代码:

    //类A头文件  要有Signals
    signals://鼠标移动信号
        void  mouseMoveSignal(); //鼠标移动
    
    //类A   某函数释放信号
    void TOPIScanningLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        emit  mouseMoveSignal();//释放信号
        QGraphicsItem::mouseMoveEvent(event);
    }
    
    //类B头文件   需要有槽函数
    public slots://槽函数
        void GetDistanceUp();//更新上图距离
    
    //类B  函数链接
    TOPIPic_Up = new TOPIScanningLine();//一定要实例化
    connect(TOPIPic_Up, SIGNAL(mouseMoveSignal()), this, SLOT(GetDistanceUp()));

     四、QT绘制直线、矩形、圆

    1.添加头文件

    #include <QPainter>

    2.重写paintEvent函数,代码如下:

    void MainWindow::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        painter.setPen(QPen(Qt::blue,2));//设置画笔形式
        painter.drawLine(20,20,220,220);//画直线
        painter.drawLine(20,220,220,20);
        painter.drawEllipse(20,20,200,200);//画圆
        painter.drawRect(20,20,200,200);//画矩形
    }

    3.函数需要在头文件中声明

    protected:
        void paintEvent(QPaintEvent *);

     

     

    转载于:https://www.cnblogs.com/aiguona/p/9995423.html

    展开全文
  • Qt中取消对象的信号与槽的关联关系 (1)关于对象取消跟其它任何对象的关联关系 实例: QObject * obj = new QObject; disconnect(obj,0,0,0); 或者 obj->disconnect(); (2)关于对象取消某个信号的关联关系 实列...
  • qt中信号槽断开连接

    千次阅读 2018-11-17 10:52:31
    qt中使用信号槽时,有时会想中途断开信号槽的连接,接下来将呈现四种连接断开方法: one:断开明确指定接受对象信号槽,如果连接断开成功返回true,否则返回false bool QObject::disconnect(const QObject *...
  • 当connect()或者disconnect()成功调用,将返回undefined;否则,将投递一个脚本异常,你可以从结果Error object获取error信息,例如: try { myQObject.somethingChanged.connect(myQObject, "...
  • QT中connect和disconnect用法总结 分类专栏: QT 文章标签: c++ qt 版权 connect用于连接信号和槽函数,但是我们经常忽略最后一个参数,本人在写代码时遇到了bug,选择一个符号进行多次标绘,再选择其他符号时,...
  • Qt】QObject详解

    2021-03-27 22:02:34
    QObject类是所以Qt类的基类,也是Qt对象模型的核心。这个模型的核心特性就是能让对象键无缝通信的信号和槽的机制。我们可以使用connect()函数将一个信号连接到一个槽上,也可以使用disconnect()删除这个连接。为了...
  • 项目遇到一个bug,经排查发现是同一个信号disconnect写法和connect写法不一致导致的, disconnect(refreshIntervalSpinBox, SIGNAL(valueChanged(double)),this, SLOT(setData())); disconnect用的qt4风格的写法...
  • 随记qt

    2014-03-22 11:44:26
    1.qt中的信号函数不需要实现,不能有返回值。 2.一个信号函数和一个信号槽用 connect()函数进行连接,disconnect()函数取消连接。 3.如果信号函数要给相应的信号槽传参,那么信号函数和信号槽函数的参数类型要...
  • Qt操作两个类的信号和槽连接

    千次阅读 2017-11-09 18:59:18
    bool flag = connect(&m_TF,SIGNAL(drawTFRect(bool)),this,SLOT(receiveTFDrawMsg(bool))); ; 看下是不是false 每执行一次connect();槽就会多响应一次,把connect()放在构造函数,或者disconnect后再connect
  • 4G_EC20模块在迅为iTOP-iMX6开发板 Qt4.7系统的移植 EC20 模块封装成标准的 PCIe 接口,和开发板主要通过 usb通讯。 此次提供的文件有 pppd 源码、编译好的 chat 和 pppd工具、wcdma,wcdma_back,wcdma-chat-...
  • Qt 语言切换

    2020-07-03 14:06:52
    void Widget::on_lanageCoBox_currentTextChanged(QString text) { if (text == QStringLiteral("简体中文")) { if (m_translator->load("widget_zh.qm")) ...disconnect(this); ui.retranslate.
  • Qt Object 类简介--Qt 类简介专题(二)   2、和connect 成双成对的disconnect 取消从sender对象发送的signal和对象receiver的member的连接。 当这两个有关对象的一个被销毁时,这个...
  • QT学习笔记(二)

    2021-01-21 14:44:16
    QT学习笔记-2021-1-21自定义信号和槽重载处理信号的连接信号连接按钮信号连接信号disconnect断开信号Lambda表达式 自定义信号和槽重载处理 昨天已经把自定信号和槽写好了,今天需要把信号设置为带参的形式。 1、在...
  • Qt槽函数的重入问题

    万次阅读 2019-11-29 18:14:36
    Qt的信号槽机制,如果一个槽函数的执行时间很长,在槽函数还没有执行结束的时候,有新的信号产生,默认情况下,该次信号不会被丢弃,而是会等槽函数执行结束后再次调用槽函数 但是在某些情况下,如果想将槽函数...
  • 最近在使用Qt做一个GUI,用于结合MySQL进行pdf类型的生产工艺文件的存储,将路径和文件名放到Mysql,将文件存在文件系统, 本来想使用ftp来做的,后来想了想,麻烦,就自己做了一个C/S来实现。 主要实现3种操作...
  • Pyqt5系列(七)-信号与槽机制 PyQt信号与槽之信号与槽的入门应用(一)...信号的connect连接最好放在__init__析构函数里面,这样只会声明一次连接,如果在类方法(函数)使用的话,要记得disconnect,否则connect会...
  • QT中元对象系统(MOC)原理

    千次阅读 2013-08-06 09:59:12
    这些函数必须在所有的QObject的子类被实现。 ●  Qt的moc工具负责执行被Q_OBJECT宏声明的函数,同时负责执行所有的信号函数。 ●  QObject的成员函数,例如connect()和disconnect()

空空如也

空空如也

1 2 3
收藏数 45
精华内容 18
关键字:

qt中disconnect