How to change the text background in QTableView
- 
I've a QLineEditto filter items in theQTableView:Window::Window(QWidget *parent) : QWidget(parent){ aModel = new QStandardItemModel(); aModel->setColumnCount(2); for (int i = 0; i < 3; i++) { auto col1 = new QStandardItem("Left " + QString::number(i + 1)); auto col2 = new QStandardItem("Right " + QString::number(i + 1)); col2->setTextAlignment(Qt::AlignVCenter|Qt::AlignRight); aModel->appendRow(QList<QStandardItem*>() << col1 << col2); col1 = new QStandardItem("Right " + QString::number(i + 1)); col2 = new QStandardItem("Left " + QString::number(i + 1)); col2->setTextAlignment(Qt::AlignVCenter|Qt::AlignRight); aModel->appendRow(QList<QStandardItem*>() << col1 << col2); } auto lay = new QVBoxLayout(this); auto combo = new CustomCombo(aModel); auto line = new QLineEdit(this); line->setPlaceholderText("Filter"); line->setClearButtonEnabled(true); auto table = new QTableView(this); auto tableProxy = new QSortFilterProxyModel(this); tableProxy->setSourceModel(aModel); tableProxy->setFilterKeyColumn(0); tableProxy->setFilterCaseSensitivity(Qt::CaseInsensitive); table->setModel(tableProxy); table->horizontalHeader()->hide(); table->verticalHeader()->hide(); lay->addWidget(combo); lay->addWidget(line); lay->addWidget(table); setLayout(lay); connect(line, &QLineEdit::textChanged, [=]{tableProxy->setFilterFixedString(line->text());}); }and it does the filter correctly:  What I want is highlight the matching string in the QTableView. Something like this: 
- 
I've a QLineEditto filter items in theQTableView:Window::Window(QWidget *parent) : QWidget(parent){ aModel = new QStandardItemModel(); aModel->setColumnCount(2); for (int i = 0; i < 3; i++) { auto col1 = new QStandardItem("Left " + QString::number(i + 1)); auto col2 = new QStandardItem("Right " + QString::number(i + 1)); col2->setTextAlignment(Qt::AlignVCenter|Qt::AlignRight); aModel->appendRow(QList<QStandardItem*>() << col1 << col2); col1 = new QStandardItem("Right " + QString::number(i + 1)); col2 = new QStandardItem("Left " + QString::number(i + 1)); col2->setTextAlignment(Qt::AlignVCenter|Qt::AlignRight); aModel->appendRow(QList<QStandardItem*>() << col1 << col2); } auto lay = new QVBoxLayout(this); auto combo = new CustomCombo(aModel); auto line = new QLineEdit(this); line->setPlaceholderText("Filter"); line->setClearButtonEnabled(true); auto table = new QTableView(this); auto tableProxy = new QSortFilterProxyModel(this); tableProxy->setSourceModel(aModel); tableProxy->setFilterKeyColumn(0); tableProxy->setFilterCaseSensitivity(Qt::CaseInsensitive); table->setModel(tableProxy); table->horizontalHeader()->hide(); table->verticalHeader()->hide(); lay->addWidget(combo); lay->addWidget(line); lay->addWidget(table); setLayout(lay); connect(line, &QLineEdit::textChanged, [=]{tableProxy->setFilterFixedString(line->text());}); }and it does the filter correctly:  What I want is highlight the matching string in the QTableView. Something like this: @Emon-Haque 
 You would need to write your ownQStyledItemDelegateto do whatever highlighting and attach it to theQTableViewviaQAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate).You will then need to persuade the view to redraw every time you type a new character causing the view to want to change its highlighting. Normally a QTableViewonly redraws in response to a model data change.
- 
@Emon-Haque 
 You would need to write your ownQStyledItemDelegateto do whatever highlighting and attach it to theQTableViewviaQAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate).You will then need to persuade the view to redraw every time you type a new character causing the view to want to change its highlighting. Normally a QTableViewonly redraws in response to a model data change.@JonB, sounds complicated. Could you please provide an example to help me understand it better? 
- 
found a solution in other forum that works with this delegate: Delegate::Delegate(){ selection.setBackground(Qt::green); /*QTextCharFormat*/} void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{ if(index.column() == 0){ QTextDocument doc(index.model()->data(index, Qt::DisplayRole).toString()); int position = 0; QTextCursor cur; do { cur = doc.find(query, position); // query is private QString cur.setCharFormat(selection); cur.movePosition(QTextCursor::Right); position = cur.position(); } while (!cur.isNull()); painter->save(); painter->translate(option.rect.x(), option.rect.y()); doc.drawContents(painter); painter->restore(); if(option.state == QStyle::State_Selected){ qDebug() << "here"; painter->fillRect(option.rect, Qt::red); } } else QStyledItemDelegate::paint(painter, option, index); }and these in mainwindow: Window::Window(QWidget *parent) : QWidget(parent){ auto lay = new QVBoxLayout(this); auto hlay = new QHBoxLayout; auto textBox = new QLineEdit(this); auto label = new QLabel(this); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); hlay->addWidget(textBox); hlay->addWidget(label); auto table = new QTableView(this); lay->addLayout(hlay); lay->addWidget(table); auto model = new QStandardItemModel; for (int i = 0; i < 50000; i++) { auto col1 = new QStandardItem("Column 1 : " + QString::number(i)); auto col2 = new QStandardItem("Column 2 : " + QString::number(i)); model->appendRow(QList<QStandardItem*>() << col1 << col2); } proxy = new QSortFilterProxyModel(table); proxy->setSourceModel(model); proxy->setFilterKeyColumn(0); table->setModel(proxy); delegate = new Delegate(); table->setItemDelegate(delegate); table->horizontalHeader()->hide(); table->verticalHeader()->hide(); label->setText(locale().toString(proxy->rowCount())); connect(textBox, &QLineEdit::textChanged, [=]{ auto query = textBox->text(); delegate->setQuery(query); proxy->setFilterFixedString(query); proxy->invalidate(); label->setText(locale().toString(proxy->rowCount())); }); } Now, when I click on an item in column 1, it doesn't highlight and doesn't print qDebug() << "here";.
- 
Another problem is when I've long text in the column I want to highlight. Here's what I wanted to achieve:  When I typed the word heardin search textbox it found 752 occurrences in this WPF app. Now here's the table without delegate: No idea why does it get 750 matches instead of 752! If I use delegate, I don't see any content in 7th column:  the delegate is same as before except the first line in paintinstead ofif(index.column() == 0), I, now have,if(index.column() == 6)and here's the content of Window:Window::Window(QWidget *parent) : QWidget(parent){ auto lay = new QVBoxLayout(this); auto hlay = new QHBoxLayout; auto textBox = new QLineEdit(this); auto label = new QLabel(this); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); hlay->addWidget(textBox); hlay->addWidget(label); auto table = new QTableView(this); lay->addLayout(hlay); lay->addWidget(table); auto db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("bukhari.db"); db.open(); auto model = new QSqlTableModel; model->setTable("Hadith"); model->select(); while (model->canFetchMore()) model->fetchMore(); db.close(); proxy = new QSortFilterProxyModel(table); proxy->setSourceModel(model); proxy->setFilterKeyColumn(6); table->setModel(proxy); delegate = new Delegate(); table->setItemDelegate(delegate); table->verticalHeader()->hide(); label->setText(locale().toString(proxy->rowCount())); connect(textBox, &QLineEdit::textChanged, [=]{ auto query = textBox->text(); delegate->setQuery(query); proxy->setFilterFixedString(query); proxy->invalidate(); label->setText(locale().toString(proxy->rowCount())); }); table->setVerticalScrollMode(QTableView::ScrollPerPixel); //table->resizeRowsToContents(); }wanted to see the whole content in the last column BUT couldn't make it work. EDIT Found the difference 2, In WPF I actually have converted string to lower before applying filter BUT in Qt I didn't and there is two Heard.
- 
found a solution in other forum that works with this delegate: Delegate::Delegate(){ selection.setBackground(Qt::green); /*QTextCharFormat*/} void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{ if(index.column() == 0){ QTextDocument doc(index.model()->data(index, Qt::DisplayRole).toString()); int position = 0; QTextCursor cur; do { cur = doc.find(query, position); // query is private QString cur.setCharFormat(selection); cur.movePosition(QTextCursor::Right); position = cur.position(); } while (!cur.isNull()); painter->save(); painter->translate(option.rect.x(), option.rect.y()); doc.drawContents(painter); painter->restore(); if(option.state == QStyle::State_Selected){ qDebug() << "here"; painter->fillRect(option.rect, Qt::red); } } else QStyledItemDelegate::paint(painter, option, index); }and these in mainwindow: Window::Window(QWidget *parent) : QWidget(parent){ auto lay = new QVBoxLayout(this); auto hlay = new QHBoxLayout; auto textBox = new QLineEdit(this); auto label = new QLabel(this); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); hlay->addWidget(textBox); hlay->addWidget(label); auto table = new QTableView(this); lay->addLayout(hlay); lay->addWidget(table); auto model = new QStandardItemModel; for (int i = 0; i < 50000; i++) { auto col1 = new QStandardItem("Column 1 : " + QString::number(i)); auto col2 = new QStandardItem("Column 2 : " + QString::number(i)); model->appendRow(QList<QStandardItem*>() << col1 << col2); } proxy = new QSortFilterProxyModel(table); proxy->setSourceModel(model); proxy->setFilterKeyColumn(0); table->setModel(proxy); delegate = new Delegate(); table->setItemDelegate(delegate); table->horizontalHeader()->hide(); table->verticalHeader()->hide(); label->setText(locale().toString(proxy->rowCount())); connect(textBox, &QLineEdit::textChanged, [=]{ auto query = textBox->text(); delegate->setQuery(query); proxy->setFilterFixedString(query); proxy->invalidate(); label->setText(locale().toString(proxy->rowCount())); }); } Now, when I click on an item in column 1, it doesn't highlight and doesn't print qDebug() << "here";.hi try with if (option.state & QStyle::State_Selected) and not if(option.state == QStyle::State_Selected){ to see if you get the qDebug() << "here"; 
- 
hi try with if (option.state & QStyle::State_Selected) and not if(option.state == QStyle::State_Selected){ to see if you get the qDebug() << "here"; @mrjj, yes that works, now I get the red background and debug output. The paintis called twice when I click an item.
- 
@mrjj, yes that works, now I get the red background and debug output. The paintis called twice when I click an item.@Emon-Haque said in How to change the text background in QTableView: @mrjj, yes that works, now I get the red background and debug output. The paintis called twice when I click an item.The reason that it works is that option.state also have other states like item is editable and 
 enabled SET already (default values) so you should use the & to test for other states as its a bit flag thing.Im not sure it means anything the paint is called twice. there can be many reasons for that. 
- 
Had to set the document size to get some content: Delegate::Delegate(){ selection.setBackground(Qt::green); /*QTextCharFormat*/} void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{ if(index.column() == 6){ if(option.state & QStyle::State_Selected) painter->fillRect(option.rect, Qt::gray); QTextDocument doc(index.model()->data(index, Qt::DisplayRole).toString()); doc.setPageSize(QSizeF(option.rect.width(), option.rect.height())); int position = 0; QTextCursor cur; do { cur = doc.find(query, position); // query is private QString cur.setCharFormat(selection); cur.movePosition(QTextCursor::Right); position = cur.position(); } while (!cur.isNull()); painter->save(); painter->translate(option.rect.x(), option.rect.y()); doc.drawContents(painter); painter->restore(); } else QStyledItemDelegate::paint(painter, option, index); }and have hidden all columns except the last and also set stretch and resizemode at the end of Window constructor: ... table->setVerticalScrollMode(QTableView::ScrollPerPixel); table->hideColumn(0); table->hideColumn(1); table->hideColumn(2); table->hideColumn(3); table->hideColumn(4); table->hideColumn(5); table->horizontalHeader()->setStretchLastSection(true); table->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);and now it's like this:  - it takes a long time to respond when I resize,
- content is jumbled,
- when I select an item it takes a while to response,
- it doesn't show whole content in the cell,
- feels like it doesn't scroll per pixel, and
- when I type in search box it shows up those text after a long time.
 EDIT Here's link of the project in GitHub for testing. The sample database, bukhari.db, has been included.
- 
It's performance is similar without the delegate and with plain single column QListView. Looks like Qt model view architecture still isn't able to handle medium size dataset.
- 
Hello, I'm designing a combobox that contains 2 column items, and can do filters and shorting based on what is typed in the combobox, the problem is that the combobox doesn't always appear when I write a search. void Dialog_Sell::getCmbStock(){ 
 QStandardItemModel *model= new QStandardItemModel(arrStock.size(), 2, this);
 for(int i=0; i<arrStock.size(); i++){
 QStandardItem *kol1 = new QStandardItem( QString("%0").arg(code[i]) );
 QStandardItem *kol2 = new QStandardItem( QString("%0").arg(name[i]) );
 model->setItem(i, 0, kol1);
 model->setItem(i, 1, kol2);
 }delegate = new Delegate(); QTableView* tableView = new QTableView( this ); QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this); proxyModel->setSourceModel(model); proxyModel->setFilterKeyColumn(-1); tableView->setModel( proxyModel); tableView->setItemDelegate(delegate); tableView->verticalHeader()->setVisible(false); tableView->horizontalHeader()->setVisible(false); tableView->setColumnWidth ( 0, 60 ); tableView->setColumnWidth ( 1, 260 ); tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); //tableView->setSelectionBehavior(QAbstractItemView::SelectRows); tableView->setStyleSheet("background-color: rgb(255, 255, 255);"); tableView->setAutoScroll(false); tableView->setShowGrid(false); tableView->setAlternatingRowColors(true); tableView->setSortingEnabled(false); tableView->setVerticalScrollMode(QTableView::ScrollPerPixel); connect(ui->cmbStock, &QComboBox::editTextChanged, [=]{ QString query = ui->cmbStock->currentText(); delegate->setQuery(query); //proxyModel->setFilterRegularExpression(query); proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); proxyModel->invalidate(); //return ; }); ui->cmbStock->setModel(proxyModel); ui->cmbStock->setView( tableView ); ui->cmbStock->setStyleSheet("QComboBox QAbstractItemView {min-width: 250px;}" "QComboBox { background-color: white; }");}  
 
