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

Access and inheritance



  • Hi,

    Have you studied the spreadsheet program of the official Qt book C++-GUI-Programming-with-Qt-4-2ndEdition?
    There in the createActions() method we have below:

    showGridAction->setChecked(spreadsheet->showGrid());

    where the spreadsheet's header/cpp doesn't have such a method showGrid(), but the spreadsheet inherits from QTableWidget inside which the showGrid() method exists.
    Yes, when that function is called, in reality, it goes and calls QTableWidget's method, I understand that.
    But I think there must have been a method with this name in spreadsheet and inside its definition it should have called its parent's (QTableWidget)showGrid() method.

    Am I not right?


  • Lifetime Qt Champion

    Hi
    You inherit the function into the spreadsheet class, so its callable via spreadsheet without it defining it also.
    It simply calls the base class function.
    Notice however, you inherited public, private or protected which
    decides what function you can call.
    So if you inherited public, you cannot call private functions via the sub class.



  • @mrjj
    Thank you. It's actually C++, I don't know why I have forgotten it! :(

    Yes, it's public inheritance.
    So, for example, when spreadsheet inherits from QTableWidget publicly, it's just like spreadsheet having a copy of all public functions of QTableWidget inside its public area. Right?


  • Lifetime Qt Champion

    @tomy
    Hi
    One could say that, but its actually more than a copy of the functions.
    The base class is part of the sub class.
    That is why we need to initialize the base from the subclass when subclass get constructed.

    If you look in Qt samples. You will notice we always call the base class constructor

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { << this part calls QMainWindow constructor with the parent parameter.
    ...
    }

    so from subclass MainWindow constructor we also call base class QMainWindow constructor so it can be setup also.



  • @mrjj
    Hi,
    you're right, but where in the constructor of MainWindow is the constructor of QMainWindow called?

    0_1549793249628_1.PNG
    0_1549793079015_Capture.PNG


  • Lifetime Qt Champion

    Hi
    In that sample it seems forgotten for mainwindow.
    But they do for spreadsheet
    Spreadsheet::Spreadsheet(QWidget *parent)
    : QTableWidget(parent) <<<<<
    {



  • @mrjj
    Hi,
    So could we have QMainWindow as a subclass of MainWindow without calling its constructor in the constructor of MainWindow?

    By the way, the book says MainWindow as a subclass of QMainWinodw!
    It seems that both are subclasses of each other! :)


  • Lifetime Qt Champion

    @tomy
    hi
    well its MainWindow as a subclass of QMainWindow
    The names are so close its sometimes confusing.
    The truth is, if a base class do not do anything in its constructor, nothing bad will happen not calling it.
    Which seems why they didnt bother here for MainWindow



  • @mrjj
    Hi, thanks, I got it.

    One other question. In page 70 of that book, about context menu, the following is written:
    "A more sophisticated way of providing context menus is to reimplement the QWidget::contextMenuEvent() function,
    create a QMenu widget, populate it with the desired actions, and call exec() on it.
    "

    If I want that sophisticated context menu, I need to reimplement the QWidget::contextMenuEvent() function. I found that here, but how to know its code to be able to change that and use it for the application please?


  • Lifetime Qt Champion

    Hi
    You would create a new subclass.
    However, it seldom useful for just a context menu and a plain QWidget.
    So where do you want to use the context menu ?

    anyway for pure learning.

    
    class MyWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit MyWidget(QWidget*parent = nullptr) : QWidget(parent)
        {
    
        }
    protected:
    // here we then override the defualt one we get from base class to have our own.
        virtual void contextMenuEvent(QContextMenuEvent *event) override
        {
            .....make menu....
        }
    };
    
    

    To use it you would either
    create from code
    MyWidget *wid=new MyWidget(this)
    and insert into layout / form.

    or use Creators promotion feature to allow to use in Designer.
    https://doc.qt.io/qt-5/designer-using-custom-widgets.html

    Note that we here inherit from QWidget
    However, it could have been from any widget. Like QPushButton etc.



  • @mrjj
    Hi, thanks.

    I forgot to say that I declared it inside the protected modifier area of MainWindow this way:

    ...
    protected:
        void closeEvent(QCloseEvent*); // Previousely added
        void contextMenuEvent(QContextMenuEvent*); // I, too, added this one
    ...
    

    and it's pure code.

    I want to use it into the spreadsheet program we talked about, to manipulate the code to have a better context menu for that program.
    One question as well, what will we achieve by re-implementing that virtual protected method please?


  • Lifetime Qt Champion

    Hi
    If you add contextMenuEvent to MainWindow, then you need
    to right click the actual MainWindow, to trigger it.
    It wont be triggered by right clicking on the spreadSheet widget.
    So not sure having them in MainWindow is what you want ?

    • One question as well, what will we achieve by re-implementing that virtual protected method please?

    Well it allows us to override a default contextMenuEvent so for any widget that can actually show a menu already( like QlineEdit)
    it allows to to alter what should be shown ( a new menu )
    Or it allows us to add a menu to a QWidget that dont already have such menu.

    BUT
    Often the signal is used instead (of the Event ) as that requires no subclass.
    https://doc.qt.io/qt-5/qwidget.html#customContextMenuRequested
    That you can just connect to and do get the same effect without subclassing.

    However, WHAT widget do you want to add contextMenu to ?
    The spreadsheet?



  • @mrjj hi,

    The spreadsheet?

    Yes. The area occupied by the cells. It actually will be used for cells.


  • Lifetime Qt Champion

    @tomy

    Hi I would use the SIGNAL then.
    I assume it has not right click menu already?
    To use it, you enable it with
    ui->spreadsheet->setContextMenuPolicy(Qt::CustomContextMenu);
    (ui->spreadsheet might not be actual name ;)

    then connect signal to a slot where you build and exec() the menu.



  • @mrjj

    I assume it has not right click menu already?

    It has. The author said: "A more sophisticated way of providing context menus is to reimplement the QWidget::contextMenuEvent() function,
    create a QMenu widget, populate it with the desired actions, and call exec() on it.", so I was motivated to re-implement that method to probably have a nicer or more advanced context menu for the cells!
    By the way, I like to use pure code only (no design mode). :)


  • Lifetime Qt Champion

    @tomy
    Well im not sure what he meant by that since its just a QMenu in any case.

    So what does it have now ?

    Im not sure why using event would be more sophisticated. Its just other way
    of having a context menu.



  • @mrjj

    So what does it have now ?

    this:

    0_1549822272949_Capture.PNG


  • Lifetime Qt Champion

    @tomy
    Hi
    Is that build from code or a default one ?
    I mean is there code to build it and show it ?



  • @mrjj Hi,
    Yes. The book also shows the code for that.
    I know I can add more options to that, for instance, to have five buttons in the context menu rather than that three ones. But by the sentence the author said, I though there should be another way to have a more advanced context menu by re-implementing the virtual protected method when mentioned earlier.

    By the way, don't you have that book?


  • Lifetime Qt Champion

    @tomy
    Hi
    Well the menu already have both shortcut and icon so not sure what else could be added.
    There is no "more advanced" menu possible by overwriting contextMenuEvent as
    you can just 100% the same just altering
    void MainWindow::createActions()
    to show what you want.

    yes, i have it as PDF. did read most of it way back.



  • @mrjj

    Thank you very much. I was too much stuck in a QML program's problem, sorry for the delay.

    If you run the program, even by the latest version of Qt Creator and on a sophisticated and fancy operating system like Windows 10, you see the program still looks old, as though we are in 2000 using it.
    Is it because of the code? If so, what parts can be updated, please?


  • Lifetime Qt Champion

    @tomy
    Hi
    Nope its just how the QWidgets look.
    If you change the icons to flat style,
    it will look more "modern"

    You could use something like
    https://github.com/laserpants/qt-material-widgets
    if you want to go all in for "modern" look.


  • Qt Champions 2019

    @tomy Do you use Qt4 or Qt5?



  • @jsulm
    It's 5.12. The latest version I think.


  • Qt Champions 2017

    @mrjj said in Access and inheritance:

    The truth is, if a base class do not do anything in its constructor, nothing bad will happen not calling it.

    Just for completeness:
    If the base class has a default constructor, and it's not called explicitly in the derived class' constructor the compiler is going to generate code to call it implicitly. Omitting it in the initializer list means nothing here, as QMainWindow() is going to be called either way. If the base class does not have a default constructor, and there's no call to the parent's constructor then this is going to generate a compile error, as the compiler has no idea what to do.



  • @kshegunov
    Hi,

    If the base class has a default constructor, and it's not called explicitly in the derived class' constructor the compiler is going to generate code to call it implicitly. Omitting it in the initializer list means nothing here, as QMainWindow() is going to be called either way.

    Is it true for the Qt Creator compiler too? (I think so)

    If the base class does not have a default constructor, and there's no call to the parent's constructor then this is going to generate a compile error, as the compiler has no idea what to do.

    Can we conclude this way that, when the base class doesn't have a constructor, in either way, whether the subclass calls the parent's constructor (!) or it doesn't, we will get an error?


  • Qt Champions 2017

    @tomy said in Access and inheritance:

    Is it true for the Qt Creator compiler too? (I think so)

    Qt Creator is not a compiler, it uses some compiler (whatever you've configured), but yes, it's true for all compiler, as this is standard (and required) behaviour for C++.

    Can we conclude this way that, when the base class doesn't have a constructor, in either way, whether the subclass calls the parent's constructor (!) or it doesn't, we will get an error?

    No. Not defining a class constructor means the compiler generates a default one for you (unless specifically told otherwise). If you haven't defined a constructor in the base class, then the derived class is going to implicitly call the automatically generated one.



  • @kshegunov

    So we will never have to call the base class's constructor from the subclass, because if there is an explicit constructor for the base class, the compiler calls (implicitly) for us (with the absence of an explicit call from us), and if there is no constructor for the base class, the compiler creates a default one and implicitly calls that in the subclass. Hence, we had better never involve ourselves with calling a base class's constructor directly (from the subclass)! :) :)


  • Lifetime Qt Champion

    @tomy
    Hi
    The automatic version is only for a default constructor.
    As soon as base class constructor takes parameters, it must be called from subclass as compiler cannot
    know how to obtain the parameters to give to base class.
    However the compiler will tell you that.


  • Qt Champions 2017

    What @mrjj said, plus the moment you define a constructor, the compiler stops generating for you. Thus if you define a constructor with parameters, the compiler will not generate a default constructor for you. Beautiful system, right? :)



  • @mrjj

    If you change the icons to flat style, it will look more "modern"

    Hi,
    The example you posted look very modern and stylish, but too advanced for me now. Thank you.
    I like to go step by step. So for the icons, I must download some "flat .png related files" from the Internet and substitute the old ones with these. Right?


  • Lifetime Qt Champion

    @tomy
    Hi
    Yes, that could be the first step.
    Maybe a bit of stylesheet to make QToolbar more flat to fit the new icons.
    I dont have an image of spreadsheet app around so im not sure what else you can
    do currently. will write of get any other ideas.



  • @kshegunov

    Beautiful system, right? :)

    Right. :)

    @mrjj

    Yes, that could be the first step.
    Maybe a bit of stylesheet to make QToolbar more flat to fit the new icons.
    I dont have an image of spreadsheet app around so im not sure what else you can
    do currently. will write of get any other ideas.

    Hi, Thanks. So I need to lookup "stylesheet".


  • Lifetime Qt Champion



  • @mrjj
    Thanks to you. :)



  • @mrjj Hi,

    I created a new project called MySpreadsheet and added a few more options to the context menu and renewed the icons to flat ones.
    Now when I run the project, it runs normally, but when we close it, the follwoing message is written in the Application Output window:

    Starting D:\Projects\Qt\MySpreadsheet\MySpreadsheet\build-MySpreadsheet-Desktop_Qt_5_12_0_MinGW_64_bit-Debug\debug\MySpreadsheet.exe...
    FTH: (243752): *** Fault tolerant heap shim applied to current process. This is usually due to previous crashes. ***
    The program has unexpectedly finished.
    The process was ended forcefully.
    D:/Projects/Qt/MySpreadsheet/MySpreadsheet/build-MySpreadsheet-Desktop_Qt_5_12_0_MinGW_64_bit-Debug/debug/MySpreadsheet.exe crashed.

    What is the problem please?
    Is it not related to the .pro file, please?


  • Qt Champions 2019

    @tomy Please run through debugger and post stack trace after it crashed...



  • @jsulm
    Do you mean by pressing F5, please?
    If so, I did it, but how to post stack trace?

    0_1550499661735_Capture_1.PNG


  • Lifetime Qt Champion

    Hi
    It is the list to the right we are after

    The code
    for entries Level 2,3 would help a lot.



  • @mrjj,
    Hi,

    0_1550500483783_1.PNG

    Do you mean I copy and paste code for level 7 and 11 here?
    7 is the project's code but 11 includes thousands of lines of code.


Log in to reply