Results 1 to 6 of 6

Thread: qt5/c++ - trying to access a QmainWindow control from another class

  1. #1
    Join Date
    Oct 2006
    Posts
    105
    Thanks
    13
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default qt5/c++ - trying to access a QmainWindow control from another class

    Hello,

    class 1
    Its a QMainWindow called mainwindow, the form contains a QComboBox (myCombo - its populated).

    class 2
    I'm trying to access a control in class 1 from class 2.
    QString where = mainwindow::myCombo->currentText();

    myCombo is private.
    error: 'QComboBox* mainwindow::myCombo' is private

    I make the QComboBox public.
    error: invalid use of member 'mainwindow::myCombo' in static member function

    I make the QComobox static.
    error: undefined reference to `mainwindow::myCombo'

    I obviously don't understand the access method.
    The internet hasn't helped me.

    Is this something to do with declaring 'extern' or maybe use signals & slots.
    Can somebody please help. Thanks in advance.

    Regards

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: qt5/c++ - trying to access a QmainWindow control from another class

    Do you know C++? Is "mainwindow" that name of the class or is it the name of a variable of type QMainWindow? If it is the name of a class, then mainwindow::myCombo is telling the compiler you want to access a static member variable called "myCombo" of the mainwindow class.

    You first need to make the instance of your mainwindow class visible to "class2", then if you have made the myCombo variable public (a dumb thing to do), you access it via "myMainWindow->myCombo->whatever()"

    The smarter way to do it is to implement a public member function in your mainwindow class that returns the combobox text:

    Qt Code:
    1. mainwindow.h:
    2. class mainwindow : public QMainWindow
    3. {
    4. //...
    5. public:
    6. const QString & getCurrentText() const { return myCombo->currentText(); }
    7. //...
    8. ];
    To copy to clipboard, switch view to plain text mode 

    Then you don't have to make "myCombo" a public variable, and in fact you can replace the QComboBox with a QFooBarBazStringWidget and the rest of your program won't know the difference. All your program needs to know is that it can ask a mainwindow instance for the current text through a method call. It doesn't need to know where that text comes from.

  3. #3
    Join Date
    Oct 2006
    Posts
    105
    Thanks
    13
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: qt5/c++ - trying to access a QmainWindow control from another class

    Hello d_stranz,

    Thanks for your reply.

    Do you know C++?
    A little, I'm trying to learn (Albeit, very slowly).

    I will have a play with your suggestion and see how far I get.
    I've got to check out the meaning of (make the instance of your mainwindow class visible to "class2").

    I will post, how I get on.

    Regards
    Qt Code:
    1. myHeaderName.h:
    2. class mainwindow : public QMainWindow
    3. {
    4. Q_OBJECT
    5.  
    6. public:
    7. mainwindow(QWidget *parent = 0);
    8. ~mainwindow();
    9. const QString & getCurrentText() const { return myCombo->currentText(); }
    10. //,,,
    11. };
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: qt5/c++ - trying to access a QmainWindow control from another class

    I've got to check out the meaning of (make the instance of your mainwindow class visible to "class2").
    In the main() method of your app, you should have something like this, right?

    Qt Code:
    1. #include <QApplication>
    2.  
    3. #include "mainwindow.h"
    4.  
    5. int main(int argc, char *argv[])
    6. {
    7. QApplication app(argc, argv);
    8.  
    9. mainWindow mainWin;
    10. mainWin.show();
    11. return app.exec();
    12. }
    To copy to clipboard, switch view to plain text mode 

    "mainWin" is an instance of the mainwindow class. In this case, there is only one instance of it in your application. You need to make a pointer to this instance visible to "class2" if you want to be able to call any of the mainwindow methods.

    You don't explain what "class2" is or how you create an instance of it. If it is being created within some method of mainwindow (like the constructor, maybe), then you can simply give the instance of class2 a pointer to the mainwindow instalce when you create it:

    Qt Code:
    1. // class2.h
    2.  
    3. #include "mainwindow.h"
    4.  
    5. class class2 : public QSomeWidget
    6. {
    7. Q_OBJECT
    8.  
    9. public:
    10. class2( QWidget * parent ) : QSomeWidget( parent ), mpMainWind( 0 ) {}
    11.  
    12. void setMainWindowPointer( mainwindow * pMW ) { mpMainWind = pMW; }
    13.  
    14. private:
    15. mainwindow * mpMainWind;
    16. }
    17.  
    18. // mainwindow.cpp
    19. class2 * mainwindow::createClass2()
    20. {
    21. class2 * pClass2 = new class2( this );
    22. pClass2->setMainWindowPointer( this );
    23. return pClass2;
    24. }
    To copy to clipboard, switch view to plain text mode 

    This is redundant, though - the parent QWidget of the class2 instance is already the mainwindow instance, so you don't need to store an extra pointer to it. However, if class2 is being created as a child of some other widget, then you will need to store the pointer as shown.

    But this stinks as far as a design goes. Widgets in a program shouldn't really have to know that much about each other or keep pointers to each other as part of their data. Qt's signals and slots mechanism was designed to allow different parts of a program to communicate information between them without the parts having to know very much about each other.

    So instead of class2 "pulling" the text from mainwindow, you could connect a slot in class2 (like, setCurrentText( const QString & )) to the QComboBox::currentTextChanged() signal from the combobox in the mainwindow UI. You do this when you create your instance of class2:

    Qt Code:
    1. // class2.h
    2.  
    3. #include <QString>
    4.  
    5. class class2 : public QSomeWidget
    6. {
    7. Q_OBJECT
    8.  
    9. public:
    10. class2( QWidget * parent ) : QSomeWidget( parent ) {}
    11.  
    12. public slots:
    13. void setCurrentText( const QString & text ) { mCurrentText = text; }
    14.  
    15. private:
    16. QString mCurrentText;
    17. }
    18.  
    19. // mainwindow.cpp
    20. class2 * mainwindow::createClass2()
    21. {
    22. class2 * pClass2 = new class2( this );
    23. connect ( myCombo, SIGNAL( currentTextChanged( const QString & ) ), pClass2, SLOT( setCurrentText( const QString & ) ) );
    24.  
    25. // If you want the class2 text to be updated any time the combobox is clicked, not just when the selection changes, then:
    26. connect ( myCombo, SIGNAL( activated( const QString & ) ), pClass2, SLOT( setCurrentText( const QString & ) ) );
    27.  
    28. return pClass2;
    29. }
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Oct 2006
    Posts
    105
    Thanks
    13
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: qt5/c++ - trying to access a QmainWindow control from another class

    Hello d_stranz,

    Thanks for your reply.

    In the main() method of your app, you should have something like this, right?
    Yes.

    You don't explain what "class2" is
    Class2 is a set of functions (only) to do with I/O and disk/file manipulation.

    You've given me somewhere to start. If the worst comes to the worst, I can revert to placing all these functions back into class1.
    They were only separated to clean things up a little.

    Regards

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: qt5/c++ - trying to access a QmainWindow control from another class

    Class2 is a set of functions (only) to do with I/O and disk/file manipulation.
    OK, so they need to know something about which file to open or something like that based on a choice made in a combo box on the main window form? And presumably you are creating a class2 instance from within your mainwindow class somewhere?

    Then I would derive class2 from QObject (making sure not to forget to add the Q_OBJECT macro at the top of the class definition). When you create it, you can choose to make the mainwindow instance the parent or not. In any case, if you need only one of them, be sure you implement the creation in such a way that you don't end up creating a new one on every button click or whatever. It's basically the same as the last code snippet I posted, changing the base class for class2:

    Qt Code:
    1. // class2.h
    2.  
    3. #include <QObject>
    4. #include <QString>
    5.  
    6. class class2 : public QObject
    7. {
    8. Q_OBJECT
    9.  
    10. public:
    11. class2( QObject * parent ) : QObject( parent ) {}
    12.  
    13. public slots:
    14. void setCurrentText( const QString & text ) { mCurrentText = text; }
    15.  
    16. private:
    17. QString mCurrentText;
    18. }
    19.  
    20. // mainwindow.cpp
    21. class2 * mainwindow::createClass2()
    22. {
    23. class2 * pClass2 = new class2( this );
    24. connect ( myCombo, SIGNAL( currentTextChanged( const QString & ) ), pClass2, SLOT( setCurrentText( const QString & ) ) );
    25.  
    26. // If you want the class2 text to be updated any time the combobox is clicked, not just when the selection changes, then:
    27. connect ( myCombo, SIGNAL( activated( const QString & ) ), pClass2, SLOT( setCurrentText( const QString & ) ) );
    28.  
    29. return pClass2;
    30. }
    To copy to clipboard, switch view to plain text mode 

    You still retain the encapsulation of your I/O methods in class2, plus you add some encapsulation and separation of the mainwindow UI objects. All mainwindow needs to know about class2 is that it has a setCurrentText slot, and class2 doesn't know anything at all about mainwindow. If class2 needs to notify mainwindow when it has finished some I/O operation, then give it a signal to pass information that mainwindow can also connect up to .

    This one of the great things about Qt's signals and slots mechanism. You could completely replace the internals of class2 while retaining the signals and slots, and mainwindow wouldn't have a clue (or need to know). Likewise, *anything* that has a signal with a const QString & argument could be connected to class2's slot, and it wouldn't know or care.

Similar Threads

  1. Replies: 4
    Last Post: 12th November 2015, 13:00
  2. Replies: 4
    Last Post: 2nd April 2013, 09:13
  3. Replies: 1
    Last Post: 29th May 2011, 08:00
  4. how to access and control QLabel by ObjectName?
    By lamp in forum Qt Programming
    Replies: 4
    Last Post: 4th November 2010, 09:31
  5. Replies: 4
    Last Post: 29th May 2010, 12:56

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.