[SOLVED] need help to subclass tabwidget's tabBar



  • I am trying to get the close button on one tab only but i get this message.
    qtabwidget.h:167: error: 'QTabBar* QTabWidget::tabBar() const' is protected, as in the code below.
    @tabWidget->tabBar()->setTabButton(1,QTabBar::LeftSide,button1);@
    I read on the net that i need to subclass the tabwidget's tabBar if i want to get it to work. I subclassed tabBar and i now get this message. mainwindow.cpp:14: error: undefined reference to `CTabWidget::CTabWidget(QWidget*)'

    I think that the class to tabwidget is not correct. below is the code that i found on the net to subclass the tabBar but it is not working correctly. thank you in advanced.

    mainwindow.h
    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    #include <QtGui>
    #include <QMainWindow>
    class CTabWidget : public QTabWidget
    {
    public:
    CTabWidget(QWidget *parent =0);
    virtual ~CTabWidget();

    QTabBar* tabBar() const { return (QTabWidget::tabBar());}
    };

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private:
    Ui::MainWindow *ui;
    };

    #endif // MAINWINDOW_H@

    mainwindow.cpp
    @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QGridLayout>

    MainWindow::MainWindow(QWidget parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    QPushButton
    button1 = new QPushButton();
    button1->setFixedWidth(20);
    button1->setIcon(*(new QIcon("information-icon.gif")));
    CTabWidget *test =new CTabWidget;
    test->tabBar()->setTabButton(1,QTabBar::LeftSide,button1);

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }@



  • You lack the implementations of the constructor and destructor of class CTabWidget (that's also what the error message says).

    And you lack the Q_OBJECT macro in the class declaration of CTabWidget.



  • Volker, i have a destructor at line 9 of the mainwindow.h. what i missed was Q_OBJECT macro but i am still getting the same error message.

    what i really think the error message is referring to is line 11 of mainwindow.h of the following code. could someone give me another example for this code.

    @QTabBar* tabBar() const { return (QTabWidget::tabBar());}@



  • Hi kalster,

    you should not overwrite a non virtual method.

    bq. I read on the net that i need to subclass the tabwidget’s tabBar if i want to get it to work. I subclassed tabBar and i now get this message. mainwindow.cpp:14: error: undefined reference to `CTabWidget::CTabWidget(QWidget*)’

    You did not subclass the tab bar, you subclassed the tab widget. You should create a subclass of QTabBar and call setTabBar to set it then.



  • i changed my class to the following code and i still get the same error message. Gerolf, i don't understand because setTabBar is not a method of tabBar.

    @class CTabBar : public QTabBar
    {
    Q_OBJECT
    public:
    CTabBar(QWidget* parent = 0);
    ~CTabBar();

    CTabBar* tabBar() const;
    

    };@



  • If you just ove4rwrite the method tabBar inside QTabWidget, you have to implement all specified methods (like constructor, destructor etc.). But what you did is overwriting a method, by subclassing QTabWidget.
    You wrote you should subclass tab bar. If access to the pointer of the QTabBar is enough, it should work the way you did it, but you also have to implement the C'tor of CTabWidget.



  • [quote author="kalster" date="1315626918"]Volker, i have a destructor at line 9 of the mainwindow.h. what i missed was Q_OBJECT macro but i am still getting the same error message.
    [/quote]

    You declared it in the header file (lines 8 + 9), but I do not see an implementation anywhere. So the actual code is missing and that most likely causes the error message "undefined reference to `CTabWidget::CTabWidget".

    Oh, and just a hint: in

    @
    QTabBar* tabBar() const { return (QTabWidget::tabBar());}
    };
    @

    please omit the parentheses around QTabWidget::tabBar(), they do not serve any purpose but maybe confuse the readers of your code :-)



  • Volker, i don't understand when you said the code is lacking the implementations of the constructor and destructor. nevertheless, i solved it with the following code. thank you Volker and Gerolf for your advice.

    @class TabWidget : public QTabWidget {
    public:
    TabWidget(QWidget *p = 0) : QTabWidget(p){}

    QTabBar *tabBar() const { return QTabWidget::tabBar(); }
    

    };@



  • Hi kalster,

    now you have implemented the c'tor:
    you added the braces :-)



  • [quote author="kalster" date="1315726966"]Volker, i don't understand when you said the code is lacking the implementations of the constructor and destructor. nevertheless, i solved it with the following code. thank you Volker and Gerolf for you advice.[/quote]

    There is a big difference between the declaration and the definition (implementation) of a class or method. It's important to know that as a C++ developer.

    The declaration is just a statement that introduces a certain name (class, method, static variable, etc.). It's basically less more than a "look, there will be a xy with a certain signature and return type bla, that you can use in your programs" (in your case: There will be a method name TabWidget with not return type and an optional QWidget pointer as argument wich happens to be the constructor).

    Your program is not complete yet, because you never told the compiler what that method actually does. This is where the definition (aka implementation) comes into the game. You can add the definition right to the declaration (like in your case, utilizing the .h header file) or you can put it into a separate .cpp implementation file.

    Also, the declaration can happen in many parts of your program (but not in more than one place for a single compiler run), but the definition must take part in a single place.

    And as a nice side effect, you can have so called forward includes for class pointers. Instead of #including the complete header file for a class MyClass in the header file of your class, you can just write:

    @
    class MyClass;
    @

    But you can have MyClass only as a pointer or reference type in the header file, not as a member variable. And of course you need to #include the header in the implementation of your class. The advantage is: it speeds up compilation, as another class including your second header file doesn't need to parse the MyClass' header file.



  • i understand the implementation (definition) now. thank you :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.