1

I'm using Qt 5.15.2 on Windows. I have a QTableWidget which has a bunch of QComboBoxes as cell widgets. The application uses the following stylesheet:

QComboBox:hover{background: yellow;}
QTableView::item:hover{color: red;}

Now when showing the table and hovering over a QComboBox on the last visible row, the table starts auto-scrolling down, like so:

enter image description here

This doesn't happen if I hover over a normal QTableWidgetItem on the last visible row as shown on the image.

If I remove either of the hover keyword from the stylesheet, then things work fine but I lose my style. My guess is that there is a conflict between QTableView::item and QComboBox when it's used as a cell widget so I've tried being more explicit about which QComboBoxes the stylesheet should apply to by using

QTableView QComboBox:hover{background: yellow;}
QTableView::item:hover{color: red;}

but that didn't help either. Any suggestions on how to solve this please?

Here is the code I've used for this example:

#include <QTableWidget>
#include <QBoxLayout>
#include <QComboBox>
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    qApp->setStyleSheet(
                "QComboBox{background: yellow;}"
                "QTableView::item:hover{color: red;}"
                        );

    auto rows = 100;
    auto cols = 5;
    auto table = new QTableWidget(rows, cols);

    for(auto i = 0; i != rows; ++i)
    {
        for(auto j = 0; j != cols; ++j)
        {
            if(j == 0)
            {
                auto item = new QTableWidgetItem("hello");
                table->setItem(i, j, item);
            }
            else
            {
                auto cb = new QComboBox();
                cb->addItems(QStringList() << "Item1" << "Item2");
                table->setCellWidget(i, j, cb);
            }
        }
    }

    table->setMinimumSize(800,600);
    table->show();
    return a.exec();
}

UPDATE

As suggested by this answer, using setAutoScroll(false) works around the issue of the autoscrolling.

Unfortunately, the table loses the ability to autoscroll when the current item changes with the directional arrows as shown below.

I've also just confirmed that the whole issue described in my post is not reproducible with Qt versions prior to Qt 5.15, so I'm guessing this is a Qt regression bug.

enter image description here

linuxfever
  • 3,763
  • 2
  • 19
  • 43

1 Answers1

1

Your QTableWidget seems to be auto-scrolling when you hover a partially visible item, my guess is that it treats it as a selected cell when hovered, which causes the auto-scroll.

To fix your issue you can simply do this:

table->setAutoScroll(false);

I applied it to your MRE and it worked.

Reasoning behind this solution:

I came up with the conclusion of your table auto-scrolling by using an eventFilter, which helped me notice QEvent::Move of the QComboBoxes, and if they are moving without me moving them, that means it's auto, so I googled this:

qtablewidget disable ensure visible

Which then led me to this answer.

Update:

to get around the auto scroll disabled for key press, you can use an event filter to basically switch in on and off, here's how:

main.cpp

#include <QApplication>
#include <QTableWidget>
#include <QComboBox>
#include <QObject>
#include <QEvent>
#include "myEventFilter.h"


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    qApp->setStyleSheet(
        "QComboBox{background: yellow;}"
        "QTableView::item:hover{color: red;}"
        );
    QString s = "della3";
    fprintf(stderr,"%s", s.toLatin1().data());

    auto rows = 100;
    auto cols = 5;
    auto table = new QTableWidget(rows, cols);

    for(auto i = 0; i != rows; ++i)
    {
        for(auto j = 0; j != cols; ++j)
        {
            if(j == 0)
            {
                auto item = new QTableWidgetItem("hello");
                table->setItem(i, j, item);
            }
            else
            {
                auto cb = new QComboBox();
                cb->addItems(QStringList() << "Item1" << "Item2");
                table->setCellWidget(i, j, cb);
            }
        }
    }

    table->setMinimumSize(800,600);
    table->setAutoScroll(false);

    myEventFilter *filter = new myEventFilter();
    table->installEventFilter(filter);
    //give the address of table to the QTableWidget pointer of the eventFilter
    filter->t=table;

    table->show();
    
    return a.exec();
}

myEventFilter.h

#ifndef MYEVENTFILTER_H
#define MYEVENTFILTER_H

#include <QObject>
#include <QEvent>
#include <QTableWidget>

class myEventFilter : public QObject
{
    Q_OBJECT

public:
    myEventFilter (QObject *parent = nullptr) {};
    //I used the below pointer to point at table
    //since it won't be able to access otherwise as far as I know
    QTableWidget *t;

protected:
    bool eventFilter(QObject *obj, QEvent *event) override
    {
        if(event->type() == QEvent::KeyPress)
        {
            t->setAutoScroll(true);
        }
        if(event->type() == QEvent::KeyRelease)
        {
            t->setAutoScroll(false);
        }

        return QObject::eventFilter(obj,event);
    };
};

#endif // MYEVENTFILTER_H

  • Thank you for looking into this, it is a good find. Unfortunately, disabling autoscrolling also affects the autoscroll when selecting items with the directional arrows, please see the update in my origina post. I've also found out that this is not reproducible with earlier Qt versions, so I'm guessing this is a Qt bug. – linuxfever Apr 06 '23 at 07:06
  • Yeah I don't think there is a way to get you the style and auto scrolling at the same time without using ugly workarounds (which I enjoy coming up with), would such type of solution interest you? I'd try to find one if it works for you, otherwise, yeah I think this is a bug, I would recommend posting this problem in Qt forum, you'd find more experienced Qt developers there. They would advise you to report it if it should be. – Abderrahmene Rayene Mihoub Apr 06 '23 at 07:21
  • That's very kind of you, thank you but it's not necessary for now. I'll post to the qt forum, see how it goes – linuxfever Apr 06 '23 at 08:45
  • This is clever, I like it. I can confirm that it solves the autoscrolling issue when hovering over cellWidgets while it also keeps the directional arrow autoscrolling active. There is another issue which I've noticed; clicking on the top left corner of the table to select all cells and then hovering over a cellWidget, the cells get deselected. It seems it's part of the same bug. For now, I think I've got what I need though, thanks again – linuxfever Apr 11 '23 at 07:11
  • You're welcome! I have looked into the new issue, using an event filter, it seems that `QTableWidget` goes out of focus when the cursor hovers an empty space, meaning a space where there is no `QTableWidgetItem` (the tiny gaps between items, and only the `QComboxes`), which deselects any selected `cellwidget`s, event if it's just one, and not necessarily starting from the top left corner. This feels like pulling the thread, or trying to patch a mummy who's wrappings are falling off. – Abderrahmene Rayene Mihoub Apr 11 '23 at 08:34