Add new tab to TabWidget when using Fusion style strange bahavior
-
After upgrading QT Creator to 14.0.0 and QT 6.7.2 I notice that there is a new style available, windows11, and when using this style this is no longer an issue. However, I have no idea if this new "windows11" style will work without issues on WIndows 10 OS. Any ideas about this concern?
Thanks@visinet said in Add new tab to TabWidget when using Fusion style strange bahavior:
Any ideas about this concern?
The windows11 style does not run on windows10 (otherwise it would have been named windows10).
Provide a minimal, compilable example of your problem and create a proper bug report so it gets fixed.
-
Ok, I don't know how, or if it is even possible, to attach a zip of the project files so here is the source. I will put in a bug report once someone verifies this actually an issue and not me doing something wrong.
.pro file
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ mainwindow.cpp HEADERS += \ mainwindow.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
Main.cpp
#include "mainwindow.h" #include <QApplication> #include <QStyleFactory> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; qApp->setStyle(QStyleFactory::create("fusion")); //needed in windows for the button qpallett color to work in changing btn color w.show(); return a.exec(); }
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_pushButtonAddNewTab_clicked(); void on_tabWidget_tabCloseRequested(int index); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButtonAddNewTab_clicked() { QWidget *NewTabWidget = new QWidget(); ui->tabWidget->addTab(NewTabWidget,QString("Tab Name")); } void MainWindow::on_tabWidget_tabCloseRequested(int index) { ui->tabWidget->removeTab(index); }
ui_mainwindow.h
/******************************************************************************** ** Form generated from reading UI file 'mainwindow.ui' ** ** Created by: Qt User Interface Compiler version 6.7.2 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ #ifndef UI_MAINWINDOW_H #define UI_MAINWINDOW_H #include <QtCore/QVariant> #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> #include <QtWidgets/QMenuBar> #include <QtWidgets/QPushButton> #include <QtWidgets/QStatusBar> #include <QtWidgets/QTabWidget> #include <QtWidgets/QWidget> QT_BEGIN_NAMESPACE class Ui_MainWindow { public: QWidget *centralwidget; QPushButton *pushButtonAddNewTab; QTabWidget *tabWidget; QWidget *tab; QWidget *tab_2; QMenuBar *menubar; QStatusBar *statusbar; void setupUi(QMainWindow *MainWindow) { if (MainWindow->objectName().isEmpty()) MainWindow->setObjectName("MainWindow"); MainWindow->resize(800, 600); centralwidget = new QWidget(MainWindow); centralwidget->setObjectName("centralwidget"); pushButtonAddNewTab = new QPushButton(centralwidget); pushButtonAddNewTab->setObjectName("pushButtonAddNewTab"); pushButtonAddNewTab->setGeometry(QRect(80, 100, 91, 24)); tabWidget = new QTabWidget(centralwidget); tabWidget->setObjectName("tabWidget"); tabWidget->setGeometry(QRect(80, 170, 461, 201)); tabWidget->setTabsClosable(true); tabWidget->setMovable(false); tab = new QWidget(); tab->setObjectName("tab"); tabWidget->addTab(tab, QString()); tab_2 = new QWidget(); tab_2->setObjectName("tab_2"); tabWidget->addTab(tab_2, QString()); MainWindow->setCentralWidget(centralwidget); menubar = new QMenuBar(MainWindow); menubar->setObjectName("menubar"); menubar->setGeometry(QRect(0, 0, 800, 21)); MainWindow->setMenuBar(menubar); statusbar = new QStatusBar(MainWindow); statusbar->setObjectName("statusbar"); MainWindow->setStatusBar(statusbar); retranslateUi(MainWindow); QMetaObject::connectSlotsByName(MainWindow); } // setupUi void retranslateUi(QMainWindow *MainWindow) { MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr)); pushButtonAddNewTab->setText(QCoreApplication::translate("MainWindow", "Add New Tab", nullptr)); tabWidget->setTabText(tabWidget->indexOf(tab), QCoreApplication::translate("MainWindow", "Tab 1", nullptr)); tabWidget->setTabText(tabWidget->indexOf(tab_2), QCoreApplication::translate("MainWindow", "Tab 2", nullptr)); } // retranslateUi }; namespace Ui { class MainWindow: public Ui_MainWindow {}; } // namespace Ui QT_END_NAMESPACE #endif // UI_MAINWINDOW_H
-
-
Why an ui file? It's a 15-liner afaics... it's a minimal compilable example, not a novel. Also ui_*.h is generated - the .ui file is needed.
int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow mw; QWidget w; mw.setCentralWidget(&w); auto pbAdd = new QPushButton("Add", &w); auto tabWidget = new QTabWidget(&w); tabWidget->setTabsClosable(true); tabWidget->setMovable(true); QObject::connect(pbAdd, &QPushButton::clicked, [&]() {tabWidget->addTab(new QWidget, "Tab"); }); QObject::connect(tabWidget, &QTabWidget::tabCloseRequested, tabWidget, &QTabWidget::removeTab); auto l = new QVBoxLayout(&w); l->addWidget(pbAdd); l->addWidget(tabWidget); mw.show(); return a.exec(); }
You are not using layouts, maybe that's the problem. I can't see any visual glitch with the fusion style on windows.
-
Sorry. I did it in the Designer, not coding it manually. so I included the Designer generated UI_****.h file just so it was obvious what exactly I was doing. Layouts are not needed at this stage but in my main project where I noticed this issue I am using layouts and have the same issue. If you are not seeing the issue when building the UI in code then maybe the issue is associated with something Designer is doing. I will try doing it via code like you included to see if I see the same issue.
-
Ok, so I think I know what is going on. The issue appears to related to tabs/pages that are added to the TabWidget at design time using the Designer vs . tabs/pages added at runtime via code. If in the Designer you remove all tabs from the TabWidget and then add tabs at runtime there is no issue because all the tabs have been added at runtime by the same code. However, if you start with one or more tabs at design time using designer and then add more tabs at runtime the issue happens. The tabs added at design time somehow have different properties/behavior than ones added at runtime. To see this behavior it appears you have to use the Designer to create a TabWidget that has at least one tab as I outlined in my initial post. It does not look like you can recreate this issue in code the way you want it. I will add the mainwindow.ui file you asked for.
Thanks
-
Here is the .ui file
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>600</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QPushButton" name="pushButtonAddNewTab"> <property name="geometry"> <rect> <x>80</x> <y>100</y> <width>91</width> <height>24</height> </rect> </property> <property name="text"> <string>Add New Tab</string> </property> </widget> <widget class="QTabWidget" name="tabWidget"> <property name="geometry"> <rect> <x>80</x> <y>170</y> <width>461</width> <height>201</height> </rect> </property> <property name="tabsClosable"> <bool>true</bool> </property> <property name="movable"> <bool>false</bool> </property> <widget class="QWidget" name="tab"> <attribute name="title"> <string>Page</string> </attribute> </widget> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>21</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
-
Ok, so I think I know what is going on. The issue appears to related to tabs/pages that are added to the TabWidget at design time using the Designer vs . tabs/pages added at runtime via code. If in the Designer you remove all tabs from the TabWidget and then add tabs at runtime there is no issue because all the tabs have been added at runtime by the same code. However, if you start with one or more tabs at design time using designer and then add more tabs at runtime the issue happens. The tabs added at design time somehow have different properties/behavior than ones added at runtime. To see this behavior it appears you have to use the Designer to create a TabWidget that has at least one tab as I outlined in my initial post. It does not look like you can recreate this issue in code the way you want it. I will add the mainwindow.ui file you asked for.
Thanks
@visinet said in Add new tab to TabWidget when using Fusion style strange bahavior:
The tabs added at design time somehow have different properties/behavior than ones added at runtime
It does not look like you can recreate this issue in code the way you want it. I will add the mainwindow.ui file you asked for.
This is not so. When you build the
.ui
file is processed byuic
tool to generate a single C++ file,ui_....h
, which you include in your code so it gets compiled. It is placed in the build output directory, not the source directory. You may look at the code of that file. That's 100% it, no magic from Designer. Whatever you think is different look at their code and compare with whatever you are doing or how to interoperate with it at runtime. -
Thanks for build process info. I do understand most of that process, but obviously not to the level and detail that you do. Is it a correct assumption that it is perfectly valid to to do what I am doing, which is simply adding a TabWidget to a form in Designer, which by default will get created with 2 tabs in it, set it's tabsClosable property to selected in Designer, and then when the program is running dynamically add additional tabs to it via the following code?
QWidget *NewTabWidget = new QWidget(); ui->tabWidget->addTab(NewTabWidget,QString("New Tab"));
If this is in fact a valid way to do this and I am not making a mistake, then all I am trying to do is report what I am seeing when using fusion mode. Note that this does not happen if the tabs are not closable, they must be set to closable.
I can't tell you why or what is causing this behavior. I have tried to figure it out by looking at the setupUI() routine where all the Designer controlled widgets stuff is located but I don't see anything obvious that might shed light on this subject so all I can do is report what I am seeing and exactly how I am building it so someone can reproduce my steps and confirm that this is an issue and not user error on my part.
I could upload a zip of my entire project if that is possible and would make things easier, but that seems like it would be more work for someone than just simply creating a new widgets project from scratch following the steps I included in my original post. It takes < 3 min to create and reproduce from new scratch project. If you are not seeing the issue with the way you are trying to recreate it then it is clearly not an issue that way, and must be associated with something that Designer is doing, wouldn't you agree? And if that is the case then the best, and maybe only way to reproduce it is by doing exactly what I am doing.
I will assist any way I can, just let me know what I can do.
Thanks again.
-
UPDATE:
Problem identified and resolved, kind of. After thinking about the difference between tabs created in the Designer and during application run time, the only thing I could think of was what the application style was set to at those 2 different times. The Designer related items are created in the constructor of the window, in the call to setupUI, and I was setting the app style to fusion after the window was getting instantiated, so the initial designer created tabs get created when the app style was set to the default, window11 in my case, but when tab were being added dynamically during the program runtime the app style had been changed to fusion. When I moved the setting of app style to before the window gets created everything works without issue.This does however raze another question/concern though. If I give the user of my application the ability to change app styles on the fly without requiring a program restart this same behavior would resurface along with potentially other unknown similar behaviors. I confirmed this to be the case in a small test app. I will search the documentation and news groups for any info related to changing styles at runtime to see how to properly do that. I would think that when a new app style is assigned it would trigger some sort of event that would cause all the application's widgets to get refreshed to implement the new style but I guess that is not %100 the case, at least not when it is done using the statement.
"qApp->setStyle(QStyleFactory::create("fusion"));"Thanks again for all the support.