QPushButtons Not Resizing
-
Hi Qt Community,
I was facing an issue where QPushButton's were not resizing when they have elided text and window is resized.
I have a tab widget, In the first tab there is a TreeView where the header contains two push buttons one to the left and other to the right. A second tab which is empty. When we reduce the width of the MainWindow the button text starts eliding.
Model.h
#ifndef CMODEL_H #define CMODEL_H #include <QAbstractItemModel> class CModel : public QAbstractItemModel { Q_OBJECT private: QStringList m_strLstLabels; public: CModel(QObject* pParent = 0); ~CModel(); QModelIndex index(int iRow, int iColumn, const QModelIndex &pParent) const; QModelIndex parent(const QModelIndex &index) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; QVariant headerData(int iSection, Qt::Orientation eOrientation, int iRole = Qt::DisplayRole) const; bool setHeaderData(int iSection, Qt::Orientation eOrientation, const QVariant &varValue, int iRole = Qt::EditRole); void clear(); }; #endif // CMODEL_H
Model.cpp
#include "Model.h" CModel::CModel(QObject* pParent) :QAbstractItemModel(pParent) , m_strLstLabels() { } CModel::~CModel() { m_strLstLabels.clear(); } QModelIndex CModel::index(int iRow, int iColumn, const QModelIndex &pParent) const { Q_UNUSED(iRow) Q_UNUSED(iColumn) Q_UNUSED(pParent) return QModelIndex(); } QModelIndex CModel::parent(const QModelIndex &index) const { Q_UNUSED(index) return QModelIndex(); } int CModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 0; } int CModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 0; } QVariant CModel::data(const QModelIndex &index, int role) const { Q_UNUSED(index); Q_UNUSED(role); return QVariant(); } QVariant CModel::headerData(int iSection, Qt::Orientation eOrientation, int iRole) const { QVariant varResult; if(eOrientation == Qt::Horizontal && iRole == Qt::DisplayRole) { varResult = m_strLstLabels.at(iSection); } else { varResult = QAbstractItemModel::headerData(iSection, eOrientation, iRole); } return varResult; } bool CModel::setHeaderData(int iSection, Qt::Orientation eOrientation, const QVariant &varValue, int iRole) { bool bResult = false; if(eOrientation == Qt::Horizontal && iRole == Qt::DisplayRole) { if(m_strLstLabels.count() == 0) { m_strLstLabels.append(varValue.toString()); bResult = true; } else { m_strLstLabels.removeAt(iSection); m_strLstLabels.insert(iSection, varValue.toString()); bResult = true; } } else { bResult = QAbstractItemModel::setHeaderData(iSection, eOrientation, varValue, iRole); } emit headerDataChanged(eOrientation, iSection, iSection); return bResult; } void CModel::clear() { beginResetModel(); m_strLstLabels.clear(); endResetModel(); }
MainWindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include "Model.h" #include <QMainWindow> #include <QTabWidget> #include <QTreeView> #include <QHBoxLayout> #include <QPushButton> #include <QHeaderView> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: void Init(); void UpdateButtonText(); protected: void resizeEvent(QResizeEvent* pEvent); private: Ui::MainWindow *ui; CModel* m_pModel; QTabWidget* m_pTabWidget; QTreeView* m_pTreeView; QPushButton* m_pButtonOne; QPushButton* m_pButtonTwo; QHBoxLayout* m_pHBoxLayout; private slots: void OnCurrentTabChanged(int iIndex); }; #endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QHBoxLayout> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , m_pModel(NULL) , m_pTabWidget(new QTabWidget(this)) , m_pTreeView(NULL) , m_pButtonOne(NULL) , m_pButtonTwo(NULL) , m_pHBoxLayout(NULL) { ui->setupUi(this); m_pModel = new CModel(this); m_pModel->clear(); m_pModel->setHeaderData(0, Qt::Horizontal, ""); Init(); connect(m_pTabWidget, SIGNAL(currentChanged(int iIndex)), this, SLOT(OnCurrentTabChanged(int iIndex))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::Init() { if(m_pTabWidget) { // Tab 1 m_pTreeView = new QTreeView(m_pTabWidget); if(m_pTreeView) { m_pTreeView->setModel((QAbstractItemModel*)m_pModel); // Create Button One m_pButtonOne = new QPushButton("Button One"); if(m_pButtonOne) { m_pButtonOne->setMaximumWidth(300); m_pButtonOne->setMinimumWidth(50); } //Create Button Two m_pButtonTwo = new QPushButton("Button Two"); if(m_pButtonTwo) { m_pButtonTwo->setMaximumWidth(300); m_pButtonTwo->setMinimumWidth(50); } m_pHBoxLayout = new QHBoxLayout(); m_pHBoxLayout->addWidget(m_pButtonOne, 0, Qt::AlignLeft); m_pHBoxLayout->addWidget(m_pButtonTwo, 0, Qt::AlignRight); m_pTreeView->header()->setLayout(m_pHBoxLayout); m_pTreeView->header()->setFixedHeight(50); m_pTabWidget->addTab(m_pTreeView, "Tree View Tab"); // Tab 2 m_pTabWidget->addTab(new QWidget(this), "Tab 2"); } this->setCentralWidget(m_pTabWidget); } } void MainWindow::UpdateButtonText() { if(m_pButtonOne && m_pButtonTwo) { QString strButtonTxt = ""; QFontMetrics fm(font()); // Update Button 1 text strButtonTxt = "Button One"; strButtonTxt = fm.elidedText(strButtonTxt, Qt::ElideRight, m_pButtonOne->width()-20); m_pButtonOne->setText(strButtonTxt); // Update Button 2 text strButtonTxt = "Button Two"; strButtonTxt = fm.elidedText(strButtonTxt, Qt::ElideRight, m_pButtonTwo->width()-20); m_pButtonTwo->setText(strButtonTxt); } } void MainWindow::OnCurrentTabChanged(int iIndex) { switch (iIndex) { case 0: { UpdateButtonText(); } break; case 1: { } break; default: break; } } void MainWindow::resizeEvent(QResizeEvent* pEvent) { Q_UNUSED(pEvent); m_pTabWidget->resize(frameSize()); UpdateButtonText(); }
Scenario:
Step 1: Open "Tree View Tab"
Step 2: Reduce the width of the window to lowest possible.
Observation: Buttons will show elided text
Step 3: Select tab 2
Step 4: Increase the width of the window.
Step 5: Select tab 1 (Tree View Tab)
Notice : Buttons didn't resize and text is not updated;Resetting button text and repainting just UpdateButtonText call didn't work;
-
@Abhi_Varma Issue found on mac os 13.4.1. Ran the same code on windows 10 its working fine. Using Qt 5.15.2
-
Hi,
Please reduce your code to the strict minimum required to reproduce your issue.
-
@Abhi_Varma You seem to be trying to replace the content of a QHeaderView by setting a layout on that widget. QHeaderview does its own layout for the section headings (e.g. to allow resizing and reordering). I am not overly surprised that trying to (ab)use it this way is not behaving as expected.
Perhaps you can explain what you are trying to achieve.
-
@ChrisW67 I'm don't think there is a default layout on header as i tried the following.
QLayout* pLayout = m_pTreeView->header()->layout(); if(pLayout) { pLayout->addWidget(m_pButtonOne); pLayout->addWidget(m_pButtonTwo); } else { qDebug() << "Layout is null"; }
it printed "Layout is null" on the output screen.
I would like to achieve the following.
i have a tab widget with 2 tabs . One tab has a tree view and other has some other widget. the tree view has one column and the column header should contain 2 buttons on each end. On clicking these button certain actions should take place(this is working fine). when i reduce the width of the window to the lowest possible. button's size also reduces and the text of the button also doesnt fit hence the elided text. after reducing the window size i'm switching to the 2nd tab and increasing the window size. Now coming back to the tab 1 its still showing the reduced buttons with elided text running the same code on windows is showing the resized buttons with full text. why in case of mac its not working properly -
@SGaist Instead of adding buttons on the header i directly added to treeview. still the same issue. below are the new files and code.
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QHBoxLayout> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , m_pTabWidget(new QTabWidget(this)) , m_pTreeView(NULL) , m_pButtonOne(NULL) , m_pButtonTwo(NULL) , m_pHBoxLayout(NULL) { ui->setupUi(this); Init(); connect(m_pTabWidget, SIGNAL(currentChanged(int iIndex)), this, SLOT(OnCurrentTabChanged(int iIndex))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::Init() { if(m_pTabWidget) { // Tab 1 m_pTreeView = new QTreeView(m_pTabWidget); if(m_pTreeView) { m_pButtonOne = new QPushButton("Button One"); m_pButtonTwo = new QPushButton("Button Two"); m_pHBoxLayout = new QHBoxLayout(); m_pHBoxLayout->addWidget(m_pButtonOne, 0, Qt::AlignLeft); m_pHBoxLayout->addWidget(m_pButtonTwo, 0, Qt::AlignRight); m_pTreeView->setLayout(m_pHBoxLayout); m_pTabWidget->addTab(m_pTreeView, "Tree View Tab"); // Tab 2 m_pTabWidget->addTab(new QWidget(this), "Tab 2"); } this->setCentralWidget(m_pTabWidget); } } void MainWindow::UpdateButtonText() { if(m_pButtonOne && m_pButtonTwo) { QString strButtonTxt = ""; QFontMetrics fm(font()); // Update Button 1 text strButtonTxt = "Button One"; strButtonTxt = fm.elidedText(strButtonTxt, Qt::ElideRight, m_pButtonOne->width()-20); m_pButtonOne->setText(strButtonTxt); // Update Button 2 text strButtonTxt = "Button Two"; strButtonTxt = fm.elidedText(strButtonTxt, Qt::ElideRight, m_pButtonTwo->width()-20); m_pButtonTwo->setText(strButtonTxt); } } void MainWindow::OnCurrentTabChanged(int iIndex) { switch (iIndex) { case 0: { UpdateButtonText(); } break; case 1: { } break; default: break; } } void MainWindow::resizeEvent(QResizeEvent* pEvent) { Q_UNUSED(pEvent); m_pTabWidget->resize(frameSize()); UpdateButtonText(); }
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTabWidget> #include <QTreeView> #include <QHBoxLayout> #include <QPushButton> #include <QHeaderView> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: void Init(); void UpdateButtonText(); protected slots: void OnCurrentTabChanged(int iIndex); protected: void resizeEvent(QResizeEvent* pEvent); private: Ui::MainWindow *ui; QTabWidget* m_pTabWidget; QTreeView* m_pTreeView; QPushButton* m_pButtonOne; QPushButton* m_pButtonTwo; QHBoxLayout* m_pHBoxLayout; }; #endif // MAINWINDOW_H
This issue has been bugging me while. Kindly help. thanks in advance.