Results 1 to 9 of 9

Thread: Problem with Qt's connectSlotsByName

  1. #1
    Join Date
    Apr 2007
    Location
    Cape Town (SA)
    Beans
    Hidden!

    Problem with Qt's connectSlotsByName

    Hi

    I'm writing a Qt application with a lot of QActions, so in order to minimise the number of connections I have to type in I'm trying connectSlotsByName. The code (stripped down) looks something like this:

    Code:
    ///// mainwindow.h
    
    class MainWindow : public QMainWindow {
       Q_OBJECT
    
       public:
          MainWindow();
    
       private:
          QAction *actFileNew;
          QMenu *menuFile;
    
       public slots:
          void on_actFileNew_triggered(bool checked = false);
    }
    
    
    ///// mainwindow.cpp
    MainWindow::MainWindow() {
       actFileNew = new QAction(QIcon(":/icons/filenew.png"), "New", this);
       menuFile = menuBar()->addMenu("&File");
       menuFile->addAction(actFileNew);
       QMetaObject::connectSlotsByName(this);
    }
    
    void MainWindow::on_actFileNew_triggered(bool checked) {
       // Code to show a message
    }
    My program compiles, but the connection doesn't appear to work - when I select the action from the menu, the message is not displayed in on_actFileNew_triggered(). It works if I make the connection manually using connect().

    Can anyone suggest why connectSlotsByName isn't working?

  2. #2
    Join Date
    Mar 2005
    Location
    Iceland
    Beans
    9
    Distro
    Edgy Eft Testing

    Re: Problem with Qt's connectSlotsByName

    Why are you using "bool checked = false" in
    Code:
    void on_actFileNew_triggered(bool checked = false);
    if you are not making this QAction checkable then it should just be
    Code:
    void on_actFileNew_triggered();

  3. #3
    Join Date
    Apr 2007
    Location
    Cape Town (SA)
    Beans
    Hidden!

    Re: Problem with Qt's connectSlotsByName

    I'm using "bool checked = false" just to match the argument for QAction::triggered. I agree it is not necessary, and I only put it in because I didn't know if it would affect connectSlotsByName. Either way, the connection isn't made.

  4. #4
    Join Date
    Mar 2005
    Location
    Iceland
    Beans
    9
    Distro
    Edgy Eft Testing

    Re: Problem with Qt's connectSlotsByName

    Auto connect is only works with objects made with the designer. All manual created objects you have to connect your self.

  5. #5
    Join Date
    Apr 2007
    Location
    Cape Town (SA)
    Beans
    Hidden!

    Re: Problem with Qt's connectSlotsByName

    That seems awkward! But when its compiling, how does it know the difference between desiger objects and coded objects? Maybe I can confuse it so it will do it.

  6. #6
    Join Date
    Mar 2009
    Beans
    2

    Lightbulb Re: Problem with Qt's connectSlotsByName

    I know this is an old thread, but I still wanted to post a reply to this topic because I had the same problem and there is a solution.

    Actually connectSlotsByName also works on classes not created by Qt Designer. You just have to specify an object name for the action for connectSlotsByName to correctly set up the signal/slot connection.

    Code:
    ///// mainwindow.cpp
    MainWindow::MainWindow() {
       actFileNew = new QAction(QIcon(":/icons/filenew.png"), "New", this);
       actFileNew->setObjectName("actFileNew");  // <<< this should do the trick
       menuFile = menuBar()->addMenu("&File");
       menuFile->addAction(actFileNew);
       QMetaObject::connectSlotsByName(this);
    }
    Cheers!
    -Stefan
    Last edited by dr.pppr; March 6th, 2009 at 07:21 PM. Reason: highlighted "object name"

  7. #7
    Join Date
    Apr 2007
    Location
    Arkansas
    Beans
    222
    Distro
    Ubuntu 9.04 Jaunty Jackalope

    Re: Problem with Qt's connectSlotsByName

    Quote Originally Posted by dr.pppr View Post
    Actually connectSlotsByName also works on classes not created by Qt Designer. You just have to specify an object name for the action for connectSlotsByName to correctly set up the signal/slot connection.
    This doesn't work for me. I'm trying to tie a event to a slot in the same class (MainWindow). Can anyone see if I'm doing something wrong?

    Thanks!

    Code:
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent), ui(new Ui::MainWindowClass)
    {
        ui->setupUi(this);
        count = 0;
    
        //connect(this, SIGNAL(testSignal()), this, SLOT(on_MainWindow_testSignal()));
    
        this->setObjectName(QString("MyWindow"));
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        cout << "test" << endl;
    
        testSignal();
    }
    
    void MainWindow::on_MyWindow_TestSignal()
    {
        cout << count << " on test signal" << endl;
        count++;
    }

  8. #8
    Join Date
    Mar 2009
    Beans
    2

    Re: Problem with Qt's connectSlotsByName

    Quote Originally Posted by jonathanmotes View Post
    This doesn't work for me. I'm trying to tie a event to a slot in the same class (MainWindow).
    You would need to call connectSlotsByName at the end of the constructor...
    Code:
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent), ui(new Ui::MainWindowClass)
    {
        ui->setupUi(this);
        count = 0;
    
        //connect(this, SIGNAL(testSignal()), this, SLOT(on_MainWindow_testSignal()));
    
        this->setObjectName(QString("MyWindow"));
        QMetaObject::connectSlotsByName(this);
    }
    ...but this code would still throw a warning during runtime that a matching signal could not be found:
    Code:
    QMetaObject::connectSlotsByName: No matching signal for on_MyWindow_testSignal()
    This is because when connectSlotsByName processes the on_MyWindow_testSignal slot it looks for a child object named "MyWindow" of the object passed as parameter (in the above case this, the instance of the MainWindow class) which it cannot find because it is not a child object but the instance itself that is named "MyWindow".

    Now if you had QObject-derived class named "MyApplication" that had a slot named "on_MyWindow_testSignal" and a member variable m_mainWindow of type MainWindow * then a call of connectSlotsByName with the instance of the MyApplication class would be able to set up a connection from the "testSignal" signal of the MainWindow instance (m_mainWindow) to the on_MyWindow_testSignal slot of the MyApplication instance because m_mainWindow would be a child object named "MyWindow" of the MyApplication instance.

    In your case you would have to set up the connection manually, but you shouldn't use the "on_" prefix for the slot's name because connectSlotsByName is also called at the end of setupUi which would again throw the warning that there is no matching signal for the slot.

    Code:
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent), ui(new Ui::MainWindowClass)
    {
        ui->setupUi(this);
        count = 0;
    
        connect(this, SIGNAL(testSignal()), SLOT(testSignalHandler()));
    }
    Hope this helps.

    Cheers!
    -Stefan

  9. #9
    Join Date
    Apr 2007
    Location
    Arkansas
    Beans
    222
    Distro
    Ubuntu 9.04 Jaunty Jackalope

    Re: Problem with Qt's connectSlotsByName

    Yes, that was very helpful!

    I was thinking that connectSlotsByName must only work for child objects. Thanks for clarifying this for me!

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •