Pointer to another class' slot



  • Hi guys,
    I'm currently trying to use Object::connect to call a slot that is defined in another class.
    The call is as follows:

    connect(ui->pbMenu, SIGNAL(clicked()), this, SLOT(master->changeForm(menu)));
    

    I'm doing it like this as I have several forms that I need to change between, and I don't to redefine the slot in every class/form when I could use a slot in the master class to handle it all, and simply call that every time I need to change forms.

    The error I'm getting is:

    QObject::connect: No such slot dtmainmenu::master->changeForm(menu) in ..//blahblahblah.....
    QObject::connect: (sender name: 'pbMenu')
    QObject::connect: (receiver name: 'dtmainmenu')

    Is it possible to have pointer to a slot that isn't directly defined in the class the class with the button within it?

    *The slot is public, and I am declaring the instance of the master class pointer within my form class. It also works just fine if I just call:

    master->changeForm(menu);
    

    without connect.

    Thanks!


  • Lifetime Qt Champion

    Hi,

    The connect statement parameters only take types not variables.

    You can use the new syntax with a lambda.



  • Sorry I should've mentioned,
    "menu" isn't a variable, it is a field in an enum declaration


  • Qt Champions 2017

    Hi @RyanR,

    as @SGaist said, it's not possible to add parameters in a connect statement.

    You could try something like this (only brain compiled):

    connect(ui->pbMenu, &QMenu::clicked, this, [menu, master]() {
        master->changeForm(menu);
    });
    

    Regards



  • @aha_1980 🤔 I think you would at least need to capture Master and menu, to use it in the lambda
    🤗


  • Qt Champions 2017

    @J.Hilk said in Pointer to another class' slot:

    @aha_1980 🤔 I think you would at least need to capture Master and menu, to use it in the lambda
    🤗

    Done



  • This post is deleted!


  • Thanks for the reply @aha_1980
    That looks like it'll accomplish exactly what I was hoping for, however I'm not sure I fully understand the syntax/parameters.
    The function declaration is the part that is throwing me off.

    Is it

    connect(myButton, 
         signal-clicked, 
         *class1, 
         [class1, class2]() 
    {
         //Function definition
    });
    

    If that's correct, why do I need to include class2 there?
    To me, it looks like I'm essentially defining a new SLOT/function as my 4th parameter, is that right?

    I appreciate all the help you guys have been providing!


    @SGaist was spot on that you cannot pass variables into the Connect parameters, so thanks for clearing that up for me!



  • Assuming master is of type Master* and menu is a pointer you can also use

    connect(ui->pbMenu, &QMenu::clicked, this, std::bind(&Master::changeForm,master,menu));
    


  • I gave that a shot, simply changing &QMenu to &QAbstractButton, as so:

    connect(ui->pbMenu, &QAbstractButton::clicked, this, std::bind(&Master::changeForm,master,menu));
    

    And it does compile and run fine, however, a Segmentation fault occurs whenever the button is clicked.
    I do have Master::changeForm(pageList p1) defined as a public slot:, but I'm assuming the error lies in the fact that the seperate class is unable to access the the changeForm function?



  • Look like you are breaking one of my assumptions:

    @VRonin said in Pointer to another class' slot:

    and menu is a pointer

    What is menu?


  • Qt Champions 2017

    @VRonin

    What is menu?

    ->

    Sorry I should've mentioned,
    "menu" isn't a variable, it is a field in an enum declaration

    Regards



  • @RyanR said in Pointer to another class' slot:

    a Segmentation fault occurs whenever the button is clicked

    Could you post the stack trace?



  • For sure, in master.cpp within the void Master::changeForm(pageList p1) function:

    Segmentation fault occurs at this->setCurrentIndex(menu_index);

    where menu_index is a member variable (int) defined in the Master as
    menu_index = addWidget(menu_pg);

    Master also extends/inherits public QStackedWidget

    Hope this helps clarify where I'm at



  • If I simply use

    connect(ui->pbMenu, SIGNAL(clicked()), this, SLOT(pbMenuClicked()));

    with the function/slot

    void myclass::pbMenuClicked()
    {
        master->changeForm(menu);
    }
    

    It works flawlessly, but I'm trying to avoid doing this.
    Essentially what I'm trying to do is eliminate the need to write out this function for every instance of a Form-changing button on each page, as I would therefore need to have this function defined across every different Form/class.
    Instead I'd like to have 1 function defined in Master that I can use Connect to point to this function every time one of my Form Change buttons are clicked.


  • Qt Champions 2017

    Hi
    But how does each button know, what menu enum it should use ?



  • As of right now, I have

    typedef enum _pageList
    {
         menu,
         page2,
         //and so on...
    }pageList;
    

    There is 1 field per page. This is used to be able to keep track of the Current page, Previous page, and in this case, which page I'd like to change to (handled by the changeForm(pageList))

    Each form has a separate button for changing to another form (1 button per form, in my case, 4). What I was hoping to do was use 3 connect's per form/class, pointing tochangeForm(PAGE-TO-CHANGE-TO) with the parameter specifying which page to change to (all handled by Master)

    As mentioned before, it seems I cannot pass parameters into SLOTS/Connect, so I also had tried simply defining 4 SLOTS in Master to call that same function to again, change pages.

    void Master::pbMenuClicked()
    {
        changeForm(menu);
    }
    

    But that brings me back to my original issue, being that I am unable to point to another class' SLOT in my connect statements which are located in each Form.


  • Qt Champions 2017

    Hi
    When you say

    • connect statements which are located in each Form.
      You mean different actual different Forms that are not in same
      Qstackedwidget(master) or by Forms you mean pages in the same
      qstackedwidget ?

    Anyway, the syntax
    connect(ui->pbMenu, &QMenu::clicked, this, std::bind(&Master::changeForm,master, menu ));
    does allow you to attach "menu" int to the clicking of the button.

    If you crash in
    this->setCurrentIndex(menu_index);
    it must mean that the master variable is invalid as
    setCurrentIndex does range check/dont crash.

    So can you show the surrounding code where u use the std::bind connect?
    I was wondering why master is not in ui?
    like
    connect(ui->pbMenu, &QAbstractButton::clicked, this, std::bind(&Master::changeForm,ui->master,menu));
    Its inserted dynamically ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.