Important: Please read the Qt Code of Conduct -

help with signals and slots

  • Hello!

    So it is high time I've learned more detailed usage of signals and slots. My current task is this: send a signal from mainwindow.cpp to another class ftpWindow.cpp. Both use the Q_OBJECT macro. MainWindow inherits QMainWindow and ftpWindow inherits QDialog. Here are the steps I am taking in attempting to do this and failing.

    1. Emit signal from MainWindow

      QString setupLocation = exists.path() + "/setup.txt"; //exists is a Qdir
      QFile file(setupLocation);
      emit sendSetupLocation(setupLocation);

    2. Connect statement in ftpWindow to the signal.

      MainWindow *test = new MainWindow(this)
      connect(test->setupScreen, SIGNAL(sendSetupLocation(QString)),
      this, SLOT(receivedSetupLocation(QString)));

      qDebug() << "myLocale is " << sentLocation;
      That should be it, right? But I get an error: QObject::connect: Cannot connect (null)::sendSetupLocation(QString) to FtpWindow::receivedSetupLocation(QString)
      and my qDebug() statement reads myLocale is "" .


  • Moderators

    If the signal is a method of MainWindow then the connect statement should be:

    connect(test, SIGNAL(sendSetupLocation(QString)),  this, SLOT(receivedSetupLocation(QString)));

    Btw. consider switching to the new syntax:

    connect(test, &MainWindow::sendSetupLocation,  this, &ftpWindow::receivedSetupLocation);

    It would catch this error at compile time.

  • @Chris-Kawa
    Thank you for the reply!

    Everything compiles fine and the connect statements auto-complete the correct pointers and signals. But myLocale still qDebugs to null.

    In the ftpWindow class, all my SLOT is doing is this:

     void FtpWindow::receivedSetupLocation(QString myLocation)
         sentLocation = myLocation;

    Does it matter that this signal is being emitted from within a QDialog that is a child of QMainWindow?

  • @Chris-Kawa

    Still having some trouble with passing a variable to another class via signals and slots.

    In the class that I'm trying to send the signal, I have in a function the following:

    void FtpWindow::downloadFile()
    MainWindow *test = new MainWindow(this);
    qDebug() << "connect statement was " <<  connect(MainWindow::setupScreen, &MainWindow::sendSetupLocation, this, &FtpWindow::receivedSetupLocation);
    qDebug() << "sentLocation is " << sentLocation;

    The qDebug() statement with the connect statement returns true but the next qDebug return null. This makes sense looking back at the post here. Does declaring a new MainWindow object here allow me to see the signals emitted from another MainWindow object? I try to do connect(MainWindow::ui, &MainWindow::sendSetupLocation .....) and i get "invalid use of non-static member 'ui' as an error.

  • Lifetime Qt Champion

    to make a new mainwindow, will not let you get signals from existing ones.
    Only from the one in connect. so u see only from "test" inside
    void FtpWindow::downloadFile(); Since you dont call test->show() i doubt u even see it on screen and it just seem wrong.

    In many other cases, the connect would be in mainwindow
    When the WhatEverdialog is created, its also connected to main.
    before shown.

    qDebug() << "sentLocation is " << sentLocation;
    That is right after the connect statement. Variable is not set here.
    it first set in your SLOT, receivedSetupLocation.
    Only there you can do
    qDebug() << "sentLocation is " << sentLocation;

    connect(MainWindow::ui, &MainWindow::sendSetupLocation .....)
    This dont make much sense. You must bind

  • @mrjj , thank you for your reply.

    Just to clarify anything, here is a breakdown of how my second class object is instantiated.

    MainWindow on button push creates a QDialog window.
    QDialog window creates another window, on button push, that is an object of my other class.

    In response to your #1, "...When the WhatEverdialog is created, its also connected to main.
    before shown."
    , I need to have a connect statement that is located before my QDialog is ->shown(). But what signal do I emit?? I don't have a place to put signals of locally created QDialogs. It would look something like connect(myQDialog, notMainWindowSignal, MainWindow::ui, mainWindowSlot()) which would then emit a signal to the other class?

    #2 response
    I call my receivedSetupLocation function and still get null values

     void FtpWindow::receivedSetupLocation(QString myLocation)
        qDebug() << "myLocation is " << myLocation; //returns null
        sentLocation = myLocation;
        qDebug() << "sentLocation is " << sentLocation; //returns null

    Does simply using a connect statement get the variable that was emitted into the slot function?

    Thank you for your help.

  • Qt Champions 2019

    @mar0029 As @mrjj already said this is just wrong:

    MainWindow *test = new MainWindow(this)
     connect(test->setupScreen, SIGNAL(sendSetupLocation(QString)), 
     this, SLOT(receivedSetupLocation(QString)));

    You create a NEW instance of MainWindow and connect its signal with the slot. You must use MainWindow instance that already exists. If your dialog is not created directly by MainWindow, but instead by another dialog then you can just pass the pointer to your MainWindow instance to the first dialog constructor which then pass it to the second dialog constructor.

    Printing the variable which is set in a slot just after connecting the signal to the slot will just print its current value (empty string in this case)., because the slot was not called yet. If you call the slot directly with a not empty string then this string should be printed.