Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

The slot is called after it is disconnected or blocked.



  • // .h - file
    class QtClipboard : public QMainWindow
    {
        Q_OBJECT
    public:
        QtClipboard(QWidget *parent = Q_NULLPTR);
     
    private:
        Ui::QtClipboardClass ui;
        QClipboard* pcb;
    // ...
    private slots:
        void clipboardChanged();
    //...
    }
     
    // .сpp - file
    QtClipboard::QtClipboard(QWidget *parent)
        : QMainWindow(parent)
    {
    ui.setupUi(this);
    //...
    pcb = QApplication::clipboard();
    connect(pcb, &QClipboard::dataChanged, this, &QtClipboard::clipboardChanged);
    }
     
    //...
     
    void QtClipboard::slotCopyToClipboard()
    {       
        const QListWidgetItem *item = listHistory->selectedItems().at(0);
        QString itemText = item->text();
        
        
        //pcb->disconnect(SIGNAL(dataChanged()), 0, 0); 
        //pcb->blockSignals(true);
        bool ret = pcb->disconnect(this); // returned true
        pcb->setText(itemText);   // This method continues to send a signal to the slot
        connect(pcb, &QClipboard::dataChanged, this, &QtClipboard::clipboardChanged); // if to comment this line slot will be disconnected successful!
        //pcb->blockSignals(false);
        //connect(pcb, &QClipboard::dataChanged, this, &QtClipboard::clipboardChanged, Qt::DirectConnection);
    }
    

  • Lifetime Qt Champion

    @extream said in The slot is called after it is disconnected or blocked.:

    connect(pcb, &QClipboard::dataChanged, this, &QtClipboard::clipboardChanged);

    This is your second connect for that signal/slot.
    First one is in constructor.



  • Yes, first time i call connect(pcb, &QClipboard::dataChanged, this, &QtClipboard::clipboardChanged) in the constructor


  • Lifetime Qt Champion

    @extream But why do you connect it twice?



  • @extream
    As @jsulm has said, you should not be connecting (same signal/slot) twice. Note also from the docs:

    By default, a signal is emitted for every connection you make; two signals are emitted for duplicate connections. You can break all of these connections with a single disconnect() call. If you pass the Qt::UniqueConnection type, the connection will only be made if it is not a duplicate. If there is already a duplicate (exact same signal to the exact same slot on the same objects), the connection will fail and connect will return an invalid QMetaObject::Connection.



  • You just need to wait 1 event loop cycle before reconnecting:
    add a private member to the class QMetaObject::Connection clipConn;

    QtClipboard::QtClipboard(QWidget *parent)
        : QMainWindow(parent)
    {
    ui.setupUi(this);
    //...
    clipConn = QObject::connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &QtClipboard::clipboardChanged);
    }
    
    void QtClipboard::slotCopyToClipboard()
    {       
        const QString itemText = listHistory->selectedItems().at(0)->text();
        QObject::disconnect(clipConn);
        QApplication::clipboard()->setText(itemText);
        QTimer::singleShot(0,this,[this](){
            if(!clipConn)
                clipConn = QObject::connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &QtClipboard::clipboardChanged);
        });
    }
    


  • @VRonin said in The slot is called after it is disconnected or blocked.:

    QTimer::singleShot(0,this,this{
    if(!clipConn)
    clipConn = QObject::connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &QtClipboard::clipboardChanged);
    });

    Tahnks! It work!


Log in to reply