2
votes

In an old program of mine, I have 2-column QTableWidget inside of a QDockWidget.

Building it in modern times (Qt 5.10) I seem to have to override the table's sizeHint() to get it to be a width besides 100px or something. Which was a bit annoying (didn't need this before--why isn't the table's width via headers the default?)

But with that tweaked, there's now another nuisance: if the user does any moving of the splitter for the dock widget, it will be lost on any window resize. I made a little MCVE to show the effect...here's the startup situation:

situation on startup

Then let's say the user drags the splitter a bit (could be expansion, could be contraction--doesn't matter):

user moves splitter

Now they drag the bottom edge of the window down a bit, and snap, it jumps back to the preferred size (the sudden jump occurs right when the mouse first starts dragging):

after window resize

Changing the horizontal size policy from QSizePolicy::Preferred to QSizePolicy::Ignored doesn't seem to influence this behavior, not calling setStretchLastSection() doesn't seem to help either.

I'd prefer if the window be resized vertically that a horizontal splitter not move at all...and if it's resized horizontally that something more gradual be done than a jump. Any ideas? Qt Creator doesn't seem to have this problem with its watchlist, but I'm not familiar enough with the source to go digging into why.

mainwindow.h:

#include <QMainWindow>

QT_BEGIN_NAMESPACE
class QTextEdit;
class SizedTableWidget;
QT_END_NAMESPACE

class SizedTableWidget;

class MainWindow : public QMainWindow {
    Q_OBJECT

    QTextEdit *textEdit;
    SizedTableWidget *table;

public:
    MainWindow ();
};

mainwindow.cpp:

#include <QtWidgets>

#include "mainwindow.h"

class SizedTableWidget : public QTableWidget {
public:
    SizedTableWidget (int rows, int columns, QWidget *parent) :
        QTableWidget (rows, columns, parent) {}

    QSize sizeHint() const {
        return QSize (
            verticalHeader()->width()
                + horizontalHeader()->length()
                + frameWidth() * 2,
            horizontalHeader()->height()
                + verticalHeader()->length()
                + frameWidth() * 2
        );
    }
};

MainWindow::MainWindow() : textEdit(new QTextEdit) {
    setCentralWidget(textEdit);

    QDockWidget *dock = new QDockWidget(tr("Table"), this);
    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);

    table = new SizedTableWidget (1 /* rows */, 2 /* cols */, dock);
    table->setHorizontalHeaderLabels(QStringList() << "name" << "value");

    QTableWidgetItem *nameItem = new QTableWidgetItem;
    nameItem->setText("foo");
    table->setItem(0, 0, nameItem);

    QTableWidgetItem *valueItem = new QTableWidgetItem;
    valueItem->setText("10");
    table->setItem(0, 1, valueItem);

    table->horizontalHeader()->setStretchLastSection(true);
    table->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);

    dock->setWidget(table);
    addDockWidget(Qt::RightDockWidgetArea, dock);
}

P.S. if anyone knows why the column and row headers on Windows don't have any styling on them, I'd be interested to know...is this on purpose? Looks fine on Linux.

System information:

  • Qt 5.10.0
  • Qt Creator 4.5.0
  • Windows 10 Home, 1709 (Build 16299.125) and MSVC 2017
  • Kubuntu Linux 17.10 and gcc 7.2.0
1
I can't reproduce the behavior you're describing on my Windows 10 machine. Can you provide more specific information as to what Windows and Qt versions you are using?RA.
It's possible you may have found a Qt bug. Can you try with Qt 5.7 and see if you can still reproduce the problem?RA.
@RA. I'm sufficiently convinced given it can be reproduced on Linux, that it didn't do it for me before (on whatever Qt I had before, that machine is dead now), and that it doesn't happen for you in 5.7. So rather than spend the rest of my day installing another Qt version and running all the associated risks with that, I've opened QTBUG-65592...we'll see what they say. Thanks for trying the MCVE for me...HostileFork says dont trust SE
Can't recreate this in Qt 5.9.3 (MSVC15) either. Also don't understand why you need the custom TableView. A regular QTV with size policy (Expanding, Expanding) seems to work just fine (always expands to fill the dock widget available size). Also I'd consider having a container QWidget (with its own layout) to hold the table, then setting the container as the QDockWidgets widget. I've done the same thing going back to Qt 4.8 and never noticed any issue.Maxim Paperno
For what it's worth I see the same "jump" behaviour on Linux/Qt5.10.0. One thing I did notice, however, is that if you drag the dock widget out of the main window and then put it back the jump/snap issue appears to have gone.G.M.

1 Answers

4
votes

This appears to be a bug--now confirmed by multiple parties--that appeared in Qt 5.10:

https://bugreports.qt.io/browse/QTBUG-65592

A proposed workaround until it is fixed is given in the comments:

Calling resizeDocks({nameOfAnyDock}, {40}, Qt::Horizontal) enabled the resize to work (the exact number is irrelevant). The function is called immediately after calling addDockWidget.