Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

open dialog in friend class



  • trying to create a dialog in a class from a different class.

    My first class had become too big, so I decided to create a new friend class and transfer a few methods to that friend class, so the first class could still call those methods.
    One of those methods creates a QInputDialog, but it gives an error over:

        GraphicsView *gv;
        
        bool ok;
        QInputDialog *dialog = new QInputDialog();
        QString text = dialog->getText(this, tr("Save As"), tr("Please enter a name: "), QLineEdit::Normal, "", &ok);
    

    Error:

    cannot initialize a parameter of type QWidget* with an.....
    

    I also tried:

        GraphicsView *gv;
        
        bool ok;
        QInputDialog *dialog = new QInputDialog();
        QString text = dialog->getText(gv, tr("Save As"), tr("Please enter a name: "), QLineEdit::Normal, "", &ok);
    

    But that gave me this error:

    no viable conversion from 'class 1' to 'QWidget*'
    

    I am curious what the best solution is in this case. I've rarely ever used friend classes and never used them in Qt.



  • @hobbyProgrammer
    Yes, I meant to write, multiple-inheritance can be a bit tricky if you're not used to it. You have to explicitly indicate which class's method you are trying to override/invoke if there is ambiguity.

    You can Google for helper class C++ for examples. For a start any methods in your current derivation which do not use this (for the QGraphicsView), or can be re-factored not to use it, are candidates for moving out. Related is also encapsulation, where you define a class which does not derive from QGraphicsView but instead has the QGraphicsView as a member, and operates on that as needed. It's a fine line to decide when best to use what in your design, but that's programming for you :)



  • gatText is static, you don't need an instance:
    QString text = QInputDialog::getText(this, tr("Save As"), tr("Please enter a name: "), QLineEdit::Normal, QString(), &ok);

    To solve your error you need to tell us what type this is



  • @VRonin it's a QGraphicsView. The first class is a customized QGraphicsView class to override some of the methods of QGraphicsView and create a custom QGraphicsView.

    So this function used to be inside the GraphicsView class and now I've transfered it to the friend class, but I still need to create a dialog.



  • so the above should work



  • @VRonin said in open dialog in friend class:

    so the above should work

    I thought that this should work, but apparently it doesn't.

    GraphicsView *gv;
        
        bool ok;
        QInputDialog *dialog = new QInputDialog();
        QString text = dialog->getText(gv, tr("Save As"), tr("Please enter a name: "), QLineEdit::Normal, "", &ok);
    

    This seems to generate an error when I include Q_OBJECT in the class declaration.

    Class contains Q_OBJECT macro but does not inherit from QObject
    

    But if I don't include Q_OBJECT I get this error:

    use of undeclared identifier 'tr'
    

  • Lifetime Qt Champion

    @hobbyProgrammer said in open dialog in friend class:

    GraphicsView

    You need to pass a QWidget pointer, so if GraphicsView doesn't derive from QWidget (directly or indirectly) you won't be able to pass it to this function - C++ basics.



  • @Christian-Ehrlicher GraphicsView derives from QGraphicsView, not QWidget. However, the constructor of GraphicsView looks like this:

    GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent)
    {
        scene = new QGraphicsScene();
        this->setScene(scene);
        this->setRenderHints(QPainter::Antialiasing);
        this->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    }
    

  • Lifetime Qt Champion

    @hobbyProgrammer said in open dialog in friend class:

    However, the constructor of GraphicsView looks like this

    This doesn't change anything: this is just a parameter for the constructor (parent) it does not make QGraphicsView a QWidget.



  • @jsulm okay but what do I need to do? I don't really get how I need to pass a QWidget pointer.
    If there is a different solution to shrink the size of my GraphicsView.cpp file, I am more than happy to hear it. (Most preferably devide methods to another source file if possible)



  • @hobbyProgrammer
    The QWidget *parent is just an optional parameter for a QWidget to be the parent of a QGraphicsView. You cannot make a QGraphicsView be a QWidget, it isn't one, not use QWidget methods on a QGraphicsView. Nothing to do with source files.

    You'll have to find some other way to "shrink the size of my GraphicsView.cpp file,". Without knowing what your code looks like it's difficult to say.

    • For example, and it's only an example, you might sub-class to multiple depths, QGraphicsView <- MySimpleGraphicsView <- MyMoreAdvancedGraphicsView <- ..., where each level of sub-class has a certain amount of related functionality but not too much, so that you can spread across multiple sub-classes/files.
    • Or, you might make your sub-class from QGraphicsView use C++ multiple inheritance, where it would derive from QGraphicsView plus some other class(es) of yours which implement additional functionality, which again could be in separate files.
    • Or, you might write a helper class which holds some of the functionality so it's not all in one file.
    • If you are saying you have some QWidget-y things you need to do around the QGraphicsView, perhaps you should write that in a QWidget-derived class which you then pass as the parent of the QGraphicsView.


  • @JonB Hi thank you so much.

    I've already tried multiple inheritance once, but it was a mess as both classed (QWidget and QGraphcisView contained some of the same functions and I've overwritten some of them and it's doesn't know which one to override, so that might not be the best solution here).
    But I've never heard of a helper class (I'm quite new to c++), but that might be the way to go.



  • @hobbyProgrammer
    Yes, I meant to write, multiple-inheritance can be a bit tricky if you're not used to it. You have to explicitly indicate which class's method you are trying to override/invoke if there is ambiguity.

    You can Google for helper class C++ for examples. For a start any methods in your current derivation which do not use this (for the QGraphicsView), or can be re-factored not to use it, are candidates for moving out. Related is also encapsulation, where you define a class which does not derive from QGraphicsView but instead has the QGraphicsView as a member, and operates on that as needed. It's a fine line to decide when best to use what in your design, but that's programming for you :)


Log in to reply