Results 1 to 13 of 13

Thread: connect to PushButton in another class: object missing in reference

  1. #1
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Question connect to PushButton in another class: object missing in reference

    Hello!

    I want to connect a function in my MainWindow-class to a PushButton in a QDialog, that could be opened from the MainWindow.
    The following message appears while compiling:

    object missing in reference to ‘Ui_AddressBook::addCustomerButton’
    MainWindow.cpp
    Qt Code:
    1. connect(AddressBook::addCustomerButton ,SIGNAL(clicked()), this, SLOT(newcustomer()));
    To copy to clipboard, switch view to plain text mode 

    addressbook.h
    Qt Code:
    1. class AddressBook : public QDialog, public Ui::AddressBook
    To copy to clipboard, switch view to plain text mode 

    ui_addressbook.h

    Qt Code:
    1. class Ui_AddressBook
    2. {
    3. public:
    4. QPushButton *addCustomerButton;
    To copy to clipboard, switch view to plain text mode 

    After typing "connect(AddressBook::" the code completion in QtCreator appears and shows the button.

    Do you know what I am doing wrong?

    Is it neccessary to connect to button to a defined object, e.g.

    Qt Code:
    1. AddressBook* test = new AddressBook;
    2. connect(test->pushButton, SIGNAL(clicked()),...
    To copy to clipboard, switch view to plain text mode 

    Or is it only possible to connect it to a class in general? Or both?

    Kind regards,
    HomeR

  2. #2
    Join Date
    Nov 2010
    Posts
    97
    Thanks
    6
    Thanked 11 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: connect to PushButton in another class: object missing in reference

    Yeah, the syntax you attempted to use is wrong for what you're trying to do. That syntax resolves a member, it doesn't specify a member within an object. If you'd put a & before it you would have been creating a member pointer.

    You need the instance->member syntax, and if there where many members of the same name within different levels of the lineage of that class you'd need to also use the resolution syntax you attempted, but in a different way: instance->AddressBook::addCustomerButton.

    In this case though you can probably just use the variable within your MainWindow, assume "addressBook" and do this:

    Qt Code:
    1. connect(addressBook->addCustomerButton, SIGNAL(clicked())....)
    To copy to clipboard, switch view to plain text mode 
    This rude guy who doesn't want you to answer his questions.

    Note: An "expert" here is just someone that's posted a lot.

    "The fact of where you do the encapsulation is meaningless." - Qt Certified Developer and forum moderator

  3. The following user says thank you to nroberts for this useful post:

    homerun4711 (29th December 2010)

  4. #3
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: connect to PushButton in another class: object missing in reference

    Ok, it works. Thank you for your answer and the explanation.

    Is it common, that in such a case the connect-statement appears directly
    after the creation of the object? E.g.

    Qt Code:
    1. AddressBook *customerlist = new AddressBook();
    2. connect(customerlist->addCustomerButton ,SIGNAL(clicked()), this, SLOT(newcustomer()));
    To copy to clipboard, switch view to plain text mode 

    I tried to connect the button in the constructor of MainWindow together with all the
    filemenu-toolbar-action-stuff, but the QDialog "AddressBook* newcustomer" is not present at that time,
    because it is opened by the user later. So I guess it its not possible to connect it before, in
    case if there will be an exiting object, or am I wrong?

  5. #4
    Join Date
    Nov 2010
    Posts
    97
    Thanks
    6
    Thanked 11 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: connect to PushButton in another class: object missing in reference

    Quote Originally Posted by homerun4711 View Post
    Ok, it works. Thank you for your answer and the explanation.

    Is it common, that in such a case the connect-statement appears directly
    after the creation of the object? E.g.

    Qt Code:
    1. AddressBook *customerlist = new AddressBook();
    2. connect(customerlist->addCustomerButton ,SIGNAL(clicked()), this, SLOT(newcustomer()));
    To copy to clipboard, switch view to plain text mode 

    I tried to connect the button in the constructor of MainWindow together with all the
    filemenu-toolbar-action-stuff, but the QDialog "AddressBook* newcustomer" is not present at that time,
    because it is opened by the user later. So I guess it its not possible to connect it before, in
    case if there will be an exiting object, or am I wrong?
    You're not wrong and this isn't unique to Qt either. The way to deal with this cleanly is to have a utility function (probably private to your main window but could be external and/or anonymous local) that's sole responsibility is prepping a new AddressBook by creating one, attaching signals, and returning it.
    This rude guy who doesn't want you to answer his questions.

    Note: An "expert" here is just someone that's posted a lot.

    "The fact of where you do the encapsulation is meaningless." - Qt Certified Developer and forum moderator

  6. #5
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: connect to PushButton in another class: object missing in reference

    The connect function always requires an existing object.
    It is a good idea to keep the connect statements as close as possible to the object creation. Or to put it in a different way, always make sure that when you create a connection, both the sender and receiver objects exist.

  7. #6
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: connect to PushButton in another class: object missing in reference

    Ok, I will try this. But how to attach a signal to a not yet existing object, in my case the AddressBook, which is not created if MainWindow is started?
    Creating the connection in AddressBook's constructor to send a signal from Addressbook to its parent MainWindow?
    Or can one attach a signal to a not yet existing object, which is connected or available if the object exists?

  8. #7
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: connect to PushButton in another class: object missing in reference

    No, you create the connection after you've created the AddressBook object.
    You can have multiple AddressBook objects, all connected to different slots or signals.
    You can't use class definitions because that would be ambiguous. The meta object compiler will not know what you want.

    So, at the point in your application, when you create a new AddressBook object, just after the creation of the object, create the connection.
    This of course also means that if the receiver or sender is the main window, the main window object should exist too.

    Example:
    MyMainWindow is the main window class.
    The openAddressBook() function creates a new AddressBook object.

    Qt Code:
    1. void MyMainWindow::openAddressBook()
    2. {
    3. AddressBook *book = new AddressBook;
    4. connect(this, SIGNAL(search(QString)), book, SLOT(search(QString)));
    5. }
    To copy to clipboard, switch view to plain text mode 

    The above example is only to demonstrate the position of the connect function in relation to the creation of the AddressBook object. The AddressBook object goes out of scope which isn't a good idea, better is to make it a member variable.
    Last edited by tbscope; 29th December 2010 at 21:18.

  9. The following user says thank you to tbscope for this useful post:

    homerun4711 (29th December 2010)

  10. #8
    Join Date
    Nov 2010
    Posts
    97
    Thanks
    6
    Thanked 11 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: connect to PushButton in another class: object missing in reference

    Quote Originally Posted by homerun4711 View Post
    Ok, I will try this. But how to attach a signal to a not yet existing object, in my case the AddressBook, which is not created if MainWindow is started?
    Creating the connection in AddressBook's constructor to send a signal from Addressbook to its parent MainWindow?
    You could do that if you want. You would need to ensure that AddressBook is always provided with your particular main window. That of course is a great reason not to do it that way since it would make your AddressBook widget very difficult to use elsewhere.

    Or can one attach a signal to a not yet existing object, which is connected or available if the object exists?
    Nope. I still recommend a utility function that builds and connects the AddressBook the way you want it connected.
    This rude guy who doesn't want you to answer his questions.

    Note: An "expert" here is just someone that's posted a lot.

    "The fact of where you do the encapsulation is meaningless." - Qt Certified Developer and forum moderator

  11. #9
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: connect to PushButton in another class: object missing in reference

    The AddressBook object goes out of scope which isn't a good idea, better is to make it a member variable.
    I don't completly understand what you mean with that, could you please explain it with a few words?

  12. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: connect to PushButton in another class: object missing in reference

    Quote Originally Posted by homerun4711 View Post
    I want to connect a function in my MainWindow-class to a PushButton in a QDialog, that could be opened from the MainWindow
    To cut to the chase... What I will propose is not directly related to your problem but indirectly it does solve it. I'd suggest improving your design -- you currently publically inherit from the UI object. The "proper" design is to inherit it privately to hide all the implementation details (such as class members) from outside world and instead only access them through getters and setters. This of course makes the following impossible:
    Qt Code:
    1. connect(customerlist->addCustomerButton ,SIGNAL(clicked()), this, SLOT(newcustomer()));
    To copy to clipboard, switch view to plain text mode 
    ... as you don't have access to "addCustomerButton". Instead your dialog should have a signal of its own that is emitted when the addCustomerButton is clicked. Then you connect to that signal instead of the original signal and should the internals of your address book class change, you don't have to modify any code other than the address book itself. Furthermore it might happen that you add some more details to the address book together with some other means to trigger adding a new customer. With your current design you'd have to make another signal/slot connection, etc. With what I suggest, you'd just emit the dialog's signal again.

    Qt Code:
    1. class AddressBook : public QDialog, private Ui::AddressBook {
    2. Q_OBJECT
    3. public:
    4. AddressBook(QWidget *parent = 0) : QDialog(parent) {
    5. setupUi(this);
    6. connect(addCustomerButton, SIGNAL(clicked()), this, SIGNAL(newCustomerRequested())); // this causes the latter to be emitted whenever the former is emitted
    7. }
    8. signals:
    9. void newCustomerRequested();
    10. };
    11.  
    12. // ...
    13. connect(customerlist, SIGNAL(newCustomerRequested()), this, SLOT(newcustomer()));
    To copy to clipboard, switch view to plain text mode 

    This all requires a bit extra coding but greatly improves the overall design. And, as I said, indirectly solves the original problem.

    Better yet newCustomer() should probably be a slot in the dialog and not in your other class.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  13. The following user says thank you to wysota for this useful post:

    homerun4711 (30th December 2010)

  14. #11
    Join Date
    Nov 2010
    Posts
    97
    Thanks
    6
    Thanked 11 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: connect to PushButton in another class: object missing in reference

    Quote Originally Posted by homerun4711 View Post
    I don't completly understand what you mean with that, could you please explain it with a few words?
    You quoted tbscope as saying, "The AddressBook object goes out of scope which isn't a good idea, better is to make it a member variable."

    They're talking about their function written above that statement:
    Qt Code:
    1. void MyMainWindow::openAddressBook()
    2. {
    3. AddressBook *book = new AddressBook;
    4. connect(this, SIGNAL(search(QString)), book, SLOT(search(QString)));
    5. }
    To copy to clipboard, switch view to plain text mode 

    It creates a memory leak because the book variable doesn't survive beyond the call to openAddressBook(). Since it was allocated on the free-store (new) it's still sitting out there, unreachable, taking up space.

    Qt has a set of ownership rules though that can be used instead of making it a member variable. You can tie the existence of that address book to the lifetime of another QObject by making that object the address book's owner (supplying it as the object constructor parameter).

    If you need to get access to it again later though, to call functions on it or whatever, you won't be able to. Whether or not you actually need to do this is another story. A lot of times in signal driven code you just need to have access to objects long enough to connect them together and then you can not care anymore. What, exactly, you need is hard to tell at this point though.

    If you didn't understand what I just said....this one is important. You'll want to read up on C++ scoping rules, memory allocation, and Qt's specific "ownership" (another thing to look up) semantics.


    Added after 17 minutes:


    Wysota's redesign of the problem is better but I'd hate to see the OP think it was better enough. One of the most frustrating things in a dialog driven interaction is when you hit 'cancel' and you're not back where you started.

    Wysota does mention that newCustomer should be in the dialog but not why. The reason why is that dialogs are often, and it appears that probably in the OP's case, generators of operations as a whole. In this case that operation might be "create/edit address book". Because we want the user to be able to cancel the operation it is not sufficient to have a button "new customer" in the dialog that creates the new customer in the main program's database. We want the dialog to track all the changes made and then IFF the user presses OK the main program either queries the dialog for information to perform the whole operation or the dialog spits up a signal that the main application is listening too.

    Often the easiest way to accomplish this is to simply send the dialog a copy of the program's database, let it alter it any way it sees fit, and then replace the original if the user presses OK. Of course, this is for small/trivial "databases" but discussing anything more complex is really beyond "newbie" level.

    In short, consider your dialog an application of its very own that takes some input...does stuff to it, and then generates output. This is nearly always the way you want your dialog to work in order to give the user what they expect. You could even simplify things for yourself if you just forget all about the main window for now and make a Qt application that simply preps your dialog, shows it, and then prints out the results or something. Starting simply and getting the dialog working FIRST since it should already be capable of existing independently of the rest of your application (minus the data it manipulates of course).
    Last edited by nroberts; 30th December 2010 at 00:09.
    This rude guy who doesn't want you to answer his questions.

    Note: An "expert" here is just someone that's posted a lot.

    "The fact of where you do the encapsulation is meaningless." - Qt Certified Developer and forum moderator

  15. The following user says thank you to nroberts for this useful post:

    homerun4711 (30th December 2010)

  16. #12
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: connect to PushButton in another class: object missing in reference

    Thanks for your good suggestions and explanations.

    So far, my QDialog is nearly standalone, but I guess this could be improved.
    Well, so much to learn about clean and tidy OOP...

  17. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: connect to PushButton in another class: object missing in reference

    Quote Originally Posted by nroberts View Post
    One of the most frustrating things in a dialog driven interaction is when you hit 'cancel' and you're not back where you started.
    That's indeed a pain in the neck, many applications cancel some operations and leave others. When working with databases there is an easy way to overcome this with two simple lines of code regardless where the code is executed. It's enough to put the whole dialog in a database transaction. Then after cancelling the dialog you simply rollback the transaction and have the exact state from before the dialog was executed. When not working with databases you can have a similar result if your application is command based (e.g. using QUndoCommand) - then you simply undo all commands performed by the dialog.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Replies: 18
    Last Post: 25th January 2010, 11:23
  2. Issue using connect, what am I missing?
    By technoViking in forum Qt Programming
    Replies: 1
    Last Post: 11th January 2010, 05:11
  3. KDE shared object file is missing
    By SimbadSubZero in forum Qt Programming
    Replies: 0
    Last Post: 13th December 2009, 14:43
  4. Replies: 12
    Last Post: 18th September 2008, 15:04
  5. Replies: 3
    Last Post: 16th May 2007, 11:07

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.