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

Template signals and multiple inheritance



  • Hello. I am working on my university project and I encountered a few problems, that I need to solve as fast as I can. I have a template class Drawer, which needs QWidget for a constructor and a QObjectSubclass, which contains just a QObject itself.
    drawer.h

    template <class Center, class Orbit>
    class Drawer : QObjectSubclass, QWidget
    {
    public:
        explicit Drawer(Center *centerItem, QWidget *parent = nullptr);
        ~Drawer();
        Center *centerItem;
        std::vector<std::tuple<Orbit*, itemWidget<Orbit>*, double>> planetObjects;
        vector<double> angles;
        vector<itemWidget<Orbit>*> widgets;
        QTimer *animation;
        QPoint *screenSize, *center;
        itemWidget<Center>* centralWidget;
        QLabel *moreInfo;
        int num=0;
        bool isMoreInfo;
        void addElem(Orbit *planet);
        void delElem(double mass);
        void startClock(){
            animation=new QTimer(this);
            connect(animation, SIGNAL(timeout()), this, SLOT(handler())); //problem
            animation->start(16);
        }
    private slots:
        void moreInfoChecker(){
            if(isMoreInfo)
                moreInfo->hide();
            else
                moreInfo->show();
            isMoreInfo=!isMoreInfo;
        }
        void handler(){
            //something more
            drawPlanets();
        }
        void drawPlanets();
    };
    

    First problem, that I have, is that connect gives me a "non-static member 'connect' has multiple-base class subobjects", I tried to add virtual to QWidget and/or QObjectSubclass, but still no results.

    And the second problem I will get, is that I will need to return template value to my MainWindow, I tried signals too, but I know, that it is impossible, how to do it properly?
    I will be pleased isа someone explained me how to solve these 2 problems? Maybe, there are some workarounds?

    Maybe, if someone will see any other solutions to these problems, I will be happy too.
    Thank you.


  • Lifetime Qt Champion

    You can't derive from two classes which has QObject as base class by design due to the parent child relationship. You have to find another way (e.g. use the second one as member).



  • @TrueNova

    In addition, making all members public is not a good style of coding :)

    What type of subclass is your QObjectSubclass?



  • Thank you @Pl45m4, I will change it later. And this is my QObjectSubclass. Yes, looks stupid, maybe... I don't know, but consider, that I am new to Qt and OOP in general.

    class QObjectSubclass : virtual public QObject
    {
        Q_OBJECT
    public:
        QObjectSubclass(QObject *parent = 0);
    };
    


  • @Christian-Ehrlicher, thank you. And sorry, what do you mean by "use the second one as member"? I am bad at English and, well, I am not really good in programming too.
    I need QWidget to make this and, probably, to paint something with QPainter(I don't know if it is actually needed).
    template <class Center, class Orbit>
    Drawer<Center, Orbit>::Drawer(Center *centerItem, QWidget *parent) : QWidget(parent)
    {

    Edit: do you mean to do something like
    class Drawer{
    Qwidget *somethig;
    }

    Then how to do the thing with constructor?


  • Lifetime Qt Champion

    You can only paint in the paintEvent() of the widget.



  • @Christian-Ehrlicher yes, I know, thank you, so what can I do to make implement this "use the second one as member" to my class for it to work, can you, please, give me a minimal of code of it?


  • Lifetime Qt Champion

    I can't and won't provide code since I don't know what you're doing and what you really want to achieve. I don't see a reason why someone would derive two times from QObject.



  • @Christian-Ehrlicher I need to make my Drawer class templated, as I know, QObject can't be so, that's why I divided it into my QObjectSubclass. Also, I need to inherit QWidget(parent) to my constructor, so I derrived my Drawer class from it too. That is why(I am pretty sure) I have this problem with connect() — "non-static member 'connect' has multiple-base class subobjects". Hope that will help you to understand my problem.


  • Lifetime Qt Champion

    @TrueNova said in Template signals and multiple inheritance:

    Hope that will help you to understand my problem.

    I understand your problem but you have to fix it another way - you can't derive two times from QObject (as already said) and templates + QObject won't work too so again - you have to find another solution.


  • Lifetime Qt Champion

    Hi,

    You are explaining the problems you are having. Can you explain exactly what you are trying to achieve ?



  • @SGaist I have classes ierarchy like tree: Galaxy->Star->Planet->Satellite and Drawer class for each one of level. I am drawing, for example, a solar system(Sun and planets on their orbits), also, I want to draw planet system(planet and its satellites)of planets of this solar system. User is in the solar system with star in the center and planets are orbiting it, the user clicks on Earth, and now Earth appers on the Screen with Moon on the orbit. I have classes to show everything on the screen for each my type, and everything works well, but I need to be able to make everything with just one template class(as all of these classes are just almost nearly identical). As my class is template, I divided a QObject into another class and then inherited it in Drawer class(found this solution on Qt Forum), but also I need to be able to send signals from this class. Here I got error message from connect().
    If you are intend to help my seriously, cause this is a really hard problem, I guess, thank you. Then this may help you: my main goal is to send some signal with undefined type(Planet-, Star-, Satellite pointers) from my template class, when user clicks on orbit item(Planet, for example). Only thing that I need, is to catch this signal from MainWindow and than put the item(this Planet), that signal sent as the central system with its orbits(Satellites) on the screen, how to achieve this goal? Cause I think, there will be a lot of problems with emitting the templated type. Are there any possible way to do, what I need at all? Thank you.


  • Lifetime Qt Champion

    What message do you want to send ?



  • @SGaist I want to do something like

    template<typename T>
    //something
    signals:
          sendItem( T* item);
    connect(item, SIGNAL(clicked()), this, SlOT(itemClicked()));
    itemClicked(){
         emit sendItem(currentItem);
    } 
    

  • Lifetime Qt Champion

    Well, looks like you are currently trying to re-implement the graphics view framework. You really should consider using it.

    On a side note, AFAIR, QObject based template class are currently not supported.

    That said, you are trying to make your planetary objects and those related to them way too smart. If you want to keep your full custom approach, you should rather give them a render method that you will call from the "main" widget paintEvent rather than trying to make each of them a full blown widget.



  • @SGaist I think I understand your vision on this task. And one more time I will review graphics view framework, but somehow it seems too hard for me now. Thank you!


Log in to reply