I wrote a custom table widget which is derived from QTableWidget
. The last two columns in this widget use a custom cell widget (one containing a QCheckBox
, the other a QLineEdit
, with some optional QPushButtons
).
Now, I added the option to color the table widget rows in a darker blue or orange color, depending on whether the checkbox is checked or not.
The code for this basically looks like the following:
// Color the standard tablewidget cells
for (auto j = 0; j < FIRST_FOUR_COLUMNS; j++) {
tableWidget->item(i, j)->setBackground(isCheckedColor);
}
QPalette palette;
palette.setColor(QPalette::Base, isCheckedColor);
// For the push buttons
palette.setColor(QPalette::Button, buttonColor);
// Now color the cell widgets
tableWidget->cellWidget(i, COL_CHECKBOX)->setAutoFillBackground(true);
tableWidget->cellWidget(i, COL_LINE_EDIT)->setAutoFillBackground(true);
tableWidget->cellWidget(i, COL_CHECKBOX)->setPalette(palette);
tableWidget->cellWidget(i, COL_LINE_EDIT)->setPalette(palette);
It works fine. However, the following occurs if a row is now selected:
The upper image shows a selected orange row, while the lower image shows a selected blue row. As you might see, the highlighting color for the last two columns is different compared to the other, standard table widget cells.
However, I want all of it to look the same.
What I tried so far was:
tableWidget->setStyleSheet("QTableWidget::item{ selection-background-color:#ff0000; }");
QItemDelegate
and overriding the paint
-method to display my own colors.Alternatives were discussed here.
But none of that worked so far, still the same problems.
How do I solve this problem?
A minimal example to reproduce the problem:
#include <QApplication>
#include <QHBoxLayout>
#include <QMainWindow>
#include <QTableWidget>
#include <QWidget>
int
main(int argc, char *argv[])
{
QApplication app(argc, argv);
// Setup widgets
auto* const tableWidget = new QTableWidget(1, 2);
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
tableWidget->setItem(0, 0, new QTableWidgetItem());
auto *const cellWidget = new QWidget;
tableWidget->setCellWidget(0, 1, cellWidget);
// Apply palette color
QPalette palette;
palette.setColor(QPalette::Base, QColor(255, 194, 10, 60));
tableWidget->item(0, 0)->setBackground(palette.color(QPalette::Base));
tableWidget->cellWidget(0, 1)->setAutoFillBackground(true);
tableWidget->cellWidget(0, 1)->setPalette(palette);
// Layout and main window
auto* const mainWindow = new QMainWindow;
auto* const layout = new QHBoxLayout;
layout->addWidget(tableWidget);
mainWindow->setCentralWidget(tableWidget);
mainWindow->show();
return app.exec();
}
CMake:
cmake_minimum_required(VERSION 3.8)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
project(ExampleProject LANGUAGES CXX)
find_package(QT NAMES Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt5 COMPONENTS Widgets REQUIRED)
add_executable(ExampleProject
${CMAKE_CURRENT_LIST_DIR}/main.cpp
)
target_link_libraries(ExampleProject
PRIVATE Qt::Widgets
)
I found a solution (or more of a workaround):
As pointed out in the comments, the problem is caused by the cell widget's alpha values. Since this value is not the maximum alpha value, the row selection and cell widget's background color are blended, creating a different highlighting color compared to the other columns.
A first, quick solution is to set the alpha value for the cell widgets to 0 so that the blending is prevented:
connect(tableWidget, &QTableWidget::itemSelectionChanged, this, [tableWidget] {
const auto selectedRows = tableWidget->selectionModel()->selectedRows();
for (const auto& selectedModel : selectedRows) {
const auto row = selectedModel.row();
auto palette = tableWidget->cellWidget(row, COL_CELL_WIDGET)->palette();
auto color = palette.color(QPalette::Base);
color.setAlpha(0);
palette.setColor(QPalette::Base, color);
tableWidget->cellWidget(row, COL_CELL_WIDGET)->setPalette(palette);
}
});
Keep in mind however, that once the item selection changes again or items are unselected, the color values for the rows which were selected before need to be changed to their old values.