QTabWidget new tabs retain old tab information/widget



  • I Currently have a custom QTabWidget class, and when ever i add a new widget to it using the QTabWidget->addTab, or QTabWidget->insertTab. the new tab ignores what ever widget i create it after, and simply becomes the widget that was previously in that location in the bar.

    EG: I have two widgets, MainPage, and SidePage, I start off with the TabWidget by adding both those widgets to it. Then if i close one of the tabs, such as the MainPage, and then try to add a new widget to the place where the old one was the new one Adds, but it just becomes the old widget

    Pictures :

    Starts like : https://i.imgur.com/8RzrsWP.png

    Adding a new Widget : https://i.imgur.com/rK9wpHF.png
    as you can see, it adds the new widget properly. But then when i close that tab and add a different widget i get:

    https://i.imgur.com/lS674tT.png

    as you can see it obtains the new title, but it remains the old widget


  • Qt Champions 2016

    hi
    Did u override any of the
    base functions in your custom QTabWidget ?
    what is the custom part?
    Sounds like page handling gone a bit funky so i wonder
    what changes might have done it.



  • Not on the QTabWidget, but i overrid (think that might be the word) the TabInserted function of the QTabBar to make it automatically assign the tab icons based on what widget is inserted.


  • Qt Champions 2016

    @SolaVitae
    i wonder if u need to call base::TabInserted also in your custom function.

    like
    yourwidget::TabInserted (xxyy) {
    BaseClass::TabInserted( x,y )
    ,,, rest of your code
    }

    but its the QTabWidget that has issue if u add, remove, add a widget page?



  • Yes i use the QtabWidget::addTab to add tabs, im not exactly very experienced with QT but it seems to pass that event to the QTabBar, since when i override the QTabWidget::tabInserted it doesnt seem to actually do anything.

    But no, calling the base tab inserted does not change anything

    EDIT: Ive sort of solved the problem by overriding the TabRemoved function from QTabBar, and just making it do Delete qTabWidget->widget(index) which works perfectly, but closing a tab closes all the tabs after it

    EG:

    We start with 2 tabs open
    https://i.imgur.com/302D7bl.png

    If i open a third tab and close the second, it closes the second tab and all tabs after it
    https://i.imgur.com/Ca5PRsv.png
    https://i.imgur.com/6YsdMYD.png

    But if i close the third tab it functions perfectly.

    Any suggestions?


  • Qt Champions 2016

    @SolaVitae

    Could you try the same code with a normal QTabWidget and
    see that add and remove "pages" does work?

    Maybe also show the code?



  • Here is the code for my stuf

    Unfortunately i cant really use a Standard QTabWidget, because i cant set the tab bar to my custom one

    rtabwidget.h

    #include <Windows.h>
    #include <QTGui>
    #include <QTWidgets>
    #include <QTCore>
    
    class MainTab : public QTabWidget
    {
    	Q_OBJECT
    public:
    	explicit MainTab(QWidget *parent = 0);
    
    private:
    
    };
    
    class MainTabBar : public QTabBar
    {
    	Q_OBJECT
    
    public:
    	explicit MainTabBar(QWidget *parent = 0);
    	virtual void tabInserted(int index);
    	void updateTabs();
    
    
    public slots:
    	void currentChangedSlot(int index);
    };
    
    
    class ActiveCloseButton : public QPushButton
    {
    	Q_OBJECT
    public:
    	explicit ActiveCloseButton(QWidget *parent = 0);
    
    public slots:
    	void buttonClicked();
    };
    
    class InactiveCloseButton : public QPushButton
    {
    	Q_OBJECT
    public:
    	explicit InactiveCloseButton(QWidget *parent = 0);
    
    public slots:
    	void buttonClicked();
    };
    
    class DisabledCloseButton : public QPushButton
    {
    	Q_OBJECT
    public:
    	explicit DisabledCloseButton(QWidget *parent = 0);
    
    
    };
    
    

    rtabwidget.cpp

    #include "rtabwidget.h"
    #include "mainwidgets.h"
    #include "QT.h"
    #include <string>
    #include <Windows.h>
    
    
    
    
    MainTab::MainTab(QWidget *parent) :
    	QTabWidget(parent)
    {
    	setStyleSheet("QWidget {background-color: rgb(124,124,124); border: none}"
    		"QTabWidget::tab-bar{ left: 8px; border: none}"
    		"QTabWidget::pane{ border : none; border-top: 4px solid rgb(175, 30, 15)}"
    	);
    	setContentsMargins(0, 0, 0, 0);
    	setGeometry(0, 68, 1024, 700);
    	setTabsClosable(true);
    	setTabBar(new MainTabBar());
    	setObjectName("MT");
    }
    
    
    
    
    MainTabBar::MainTabBar(QWidget *parent) :
    	QTabBar(parent)
    {
    	connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChangedSlot(int)));
    	connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequestSlot(int)));
    	setObjectName("MTBar");
    
    	setContentsMargins(0, 0, 0, 0);
    	setTabsClosable(true);
    	setStyleSheet(
    		"QTabBar { left: 8px; background-color: transparent; border: none; qproperty-drawBase: 0 }"
    		"QTabBar::tab { padding: 4px; width: 135px; height: 15px; border-top-left-radius: 4px; border-top-right-radius: 4px}"
    		"QTabBar::tab:selected { background-color: rgb(124,124,124); margin-left: 5px; margin-right: 5px;}"
    		"QTabBar::tab:!selected{ background-color: rgb(108,108,108); margin-left: 5px; margin-right: 5px;}"
    	);
    
    
    
    }
    
    void MainTabBar::tabInserted(int index)
    {
    	QTabBar::tabInserted(index);
    	setTabButton(index, QTabBar::RightSide, new ActiveCloseButton);
    	MainTab* mainTab = dynamic_cast<MainTab*>(parentWidget());
    	QWidget* tWidget = mainTab->widget(index);
    	std::string classType = typeid(*tWidget).name();
    	QIcon* tIcon;
    	tIcon = new QIcon();
    	if (classType.compare("class HomePage") == 0)
    		tIcon = dynamic_cast<QIcon*>(dynamic_cast<HomePage*>(tWidget)->icon);
    	if (classType.compare("class ItemSearch") == 0)
    		tIcon = dynamic_cast<QIcon*>(dynamic_cast<ItemSearch*>(tWidget)->icon);
    
    	setTabIcon(index, *tIcon);
    	setIconSize(QSize(24, 24));
    	setCurrentIndex(index);
    	updateTabs();
    
    
    }
    
    void MainTabBar::updateTabs() {
    	int activeIndex =  currentIndex();
    	QWidget* tWidget;
    	if (count() > 1) {
    		for (int c = 0; c < count(); c++) {
    			tWidget = dynamic_cast<MainTab*>(parentWidget())->widget(c);
    			if (c != activeIndex && tWidget != 0)
    				setTabButton(c, QTabBar::RightSide, new InactiveCloseButton);
    			else if (tWidget != 0)
    				setTabButton(c, QTabBar::RightSide, new ActiveCloseButton);
    		}
    	}
    	else
    		setTabButton(dynamic_cast<MainTab*>(parentWidget())->currentIndex(), QTabBar::RightSide, new DisabledCloseButton);
    
    }
    
    void MainTabBar::currentChangedSlot(int index) {
    	updateTabs();
    }
    
    
    ActiveCloseButton::ActiveCloseButton(QWidget *parent) :
    	QPushButton(parent)
    {
    	setStyleSheet(
    		"QPushButton {border-image: url(:/res/img/icons/closetab-active.png); border: none; background-color: transparent}"
    		"QPushButton:hover {border-image: url(:/res/img/icons/closetab-activeselected.png)}"
    	);
    
    	connect(this, SIGNAL(pressed()), this, SLOT(buttonClicked()));
    	setFixedSize(18, 18);
    
    }
    
    void ActiveCloseButton::buttonClicked() {
    	QPoint *windowPoint = new QPoint(x(), y());
    	MainTabBar *parent = dynamic_cast<MainTabBar*>(parentWidget());
    	MainTab *mt = parentWidget()->parentWidget()->findChild<MainTab*>("MT");
    	int index = parent->tabAt(*windowPoint);
    	OutputDebugString("Button Pressed");
    	if (parent->count() > 1) {
    		parent->removeTab(index);
    	}
    	parent->updateTabs();
    
    
    }
    
    
    InactiveCloseButton::InactiveCloseButton(QWidget *parent) :
    	QPushButton(parent)
    {
    	setStyleSheet(
    		"QPushButton {max-height: 18px; max-width: 18px; background-color: transparent; border-image: url(:/res/img/icons/closetab-inactive.png); border: none}"
    		"QPushButton:hover {border-image: url(:/res/img/icons/closetab-activeselected.png)}"
    	
    	);
    
    	connect(this, SIGNAL(pressed()), this, SLOT(buttonClicked()));
    	setFixedSize(18, 18);
    
    }
    
    void InactiveCloseButton::buttonClicked() {
    	QPoint *windowPoint = new QPoint(x(), y());
    	MainTabBar *parent = dynamic_cast<MainTabBar*>(parentWidget());
    	MainTab *mt = parentWidget()->parentWidget()->findChild<MainTab*>("MT");
    	int index = parent->tabAt(*windowPoint);
    	OutputDebugString("Button Pressed");
    	if (parent->count() > 1) {
    		parent->removeTab(index);
    	}
    	parent->updateTabs();
    }
    
    
    DisabledCloseButton::DisabledCloseButton(QWidget *parent) :
    	QPushButton(parent)
    {
    	setStyleSheet(
    		"QPushButton {max-height: 18px; max-width: 18px; background-color: transparent; border-image: url(:/res/img/icons/closetab-inactive.png); border: none}"
    	);
    	setFixedSize(18, 18);
    
    }
    
    

  • Qt Champions 2016

    sorry , nothing pop to eye.
    I think only way is with debugger and single step to find how it can become the old.



  • im not sure what you mean by that, im pretty new to coding and i use VS2015


  • Qt Champions 2016

    @SolaVitae
    ok.
    VS also have debugger. you might need to install it.
    it lets you stop and inspect the variables.
    that way you can execute the remove and add of a tab and see the variables, step
    by step. since the object normally works, we must assume it is something in the child class.

    so google how to use debugger in vs
    or from ms
    https://msdn.microsoft.com/en-us/library/mt243867.aspx
    and single the updateTabs and tabInserted



  • i added breakpoints to the tabInserted, as well as the actions that add the new tabs, nothing seems amiss, it shows that it IS adding a new widget every time when i click the button, it just seems to make the index permanently the first widget that has been assigned to that particular index. But i have noticed when you close a tab, and the tab bar automatically moves your tab into the old ones place, the moved tab becomes the old one

    EG:

    https://i.imgur.com/ckm58nK.png

    Then when i close the second one labeled "Home Page"

    https://i.imgur.com/CRoRCd6.png

    Also here is the code that adds widgets, just incase there is an issue with it

    void ItemBox::act0t() {
    	MainTab *mt = parentWidget()->parentWidget()->findChild<MainTab*>("MT");
    	int x = mt->count();
    	//delete mt->widget(x);
    	int t = mt->addTab(new ItemSearch(), "Item Search");
    
    }
    void ItemBox::act1t() {
    	MainTab *mt = parentWidget()->parentWidget()->findChild<MainTab*>("MT");
    	int x = mt->count();
    	//delete mt->widget(x);
    	int t = mt->addTab(new HomePage(), "Home Page");
    
    }
    

    Those actions are simply actions on a QPushButton menu

    EDIT: I seem to have fixed it simply by changing when i remove the tabs from doing QTabBar::removeTab, to QTabWidget::removeTab, and now everything works perfectly. I feel quite stupid for not trying that a lot sooner, but thank you for all of your assistance in troubleshooting


  • Qt Champions 2016

    super :)
    its easy to overlook stuff in own code :)


Log in to reply
 

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