How to reset tab order in QHeaderView?
-
Right now the only way to go to the next QlineEdit in the header is click. If I press tab on any of these QLineEdit, it goes to the cell of QTableView like this:
Here's how I've added those QLineEdit in the header:
void TableHeader::resetBoxes(int count){ if(lineEdits.size()) { foreach(auto line, lineEdits) line->disconnect(); qDeleteAll(lineEdits); lineEdits.clear(); queries.clear(); } for (int i = 0; i < count; i++) { auto edit = new QLineEdit(this); lineEdits.append(edit); queries.append(""); connect(edit, &QLineEdit::textChanged, this, &TableHeader::textChanged); edit->show(); } }
How to change this behavior? A side qustion, right now I've a
QSortFilterProxyModel
named TableProxyModel and in it, I've this:bool TableProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const{ bool match = true; for (int i = 0; i < sourceModel()->columnCount(); i++) { if(queries[i] != ""){ if(sourceModel()->data(sourceModel()->index(row, i)).toString().contains(queries.at(i))) continue; match = false; break; } } return match; }
so here I'm checking every columns of that row. Can I give it, or some other Model/ProxyModel, an expression like:
Col1 = 10 AND Col2 >= 20 AND Col3 = someString AND col4 LIKE someOtherString
for accepting/rejecting rows? Something like the DataView RowFilter expression of .net.
-
Then maybe an event filter.
-
Hi,
setTabOrder comes to mind for that.
As for your complex expression, it's up to you to build a parser for it.
If it's a simple "and" statement, you could build a hash with a vector of column and the value that should be checked. And then use that hash to inspect all the elements that forms the expression.
-
Hi,
setTabOrder comes to mind for that.
As for your complex expression, it's up to you to build a parser for it.
If it's a simple "and" statement, you could build a hash with a vector of column and the value that should be checked. And then use that hash to inspect all the elements that forms the expression.
@SGaist, tried
if(i > 0) setTabOrder(lineEdits[i - 1], edit);
andif(i > 0) QWidget::setTabOrder(lineEdits[i - 1], edit);
in the for loop where I add those QLineEdit with and withouttable->setFocusPolicy(Qt::ClickFocus);
. Doesn't work.EDIT
Also triedsetFocusPolicy(Qt::TabFocus);
in the constructor ofTableHeader
. -
Then maybe an event filter.
-
Then maybe an event filter.
@SGaist, not sure whether I've implemented in correct way in right place. Here's what I've in the subclass of
QHeaderView
:bool TableHeader::eventFilter(QObject *o, QEvent *e){ for (int i = 0; i < lineEdits.size(); i++) { qDebug() << "here"; if(lineEdits[i] != o) continue; if(e->type() != QEvent::KeyPress) return false; auto event = static_cast<QKeyEvent*>(e); if(event->key() != Qt::Key_Tab) return false; if(i == lineEdits.size()) lineEdits[0]->setFocus(Qt::FocusReason::OtherFocusReason); else lineEdits[i + 1]->setFocus(Qt::FocusReason::OtherFocusReason); return true; } return QHeaderView::eventFilter(o, e); }
I don't see it printing
here
in Qt Creator's output window. One more thing, when I don't have any table cell visible, TAB works automatically BUT if I have any table cell visible, it doesn't work: -
You did you install the filter ?
-
@SGaist, missed that, now it works. Thanks. Two more question:
- do I have to uninstall the filter when I remove some of those line edits?
- do I have to call
line->disconnect()
as I remove and delete line edit or it'll be automatically disconnected when I delete?
-
- do you mean delete ? Then no
- nothing particular to do.
-
@SGaist, yes with the keyword
delete line
orline.deleteLater()
. -
So the answer is no.
-
Hi,
setTabOrder comes to mind for that.
As for your complex expression, it's up to you to build a parser for it.
If it's a simple "and" statement, you could build a hash with a vector of column and the value that should be checked. And then use that hash to inspect all the elements that forms the expression.
@SGaist,
QSqlTableModel
actually has that feature and I can give it an expression like that in itssetFilter
to accept/reject rows like this:Here's the code I used for that:
void TableWidget::refreshModel(){ auto queries = tableHeader->getQueries(); QString expression; for (int i = 0; i < queries.size(); i++) { if(queries[i] == "") continue; auto column = tableModel->headerData(i, Qt::Horizontal).toString() + " " + queries[i] + " AND "; expression += column; } tableModel->setFilter(expression.left(expression.length() - 5)); // -5 to remove last " AND " if(tableModel->lastError().type() != QSqlError::NoError){ tableModel->setFilter(""); // do someting else here if you want tableModel->select(); } while (tableModel->canFetchMore()) tableModel->fetchMore(); countLable->setText(QString::number(tableModel->rowCount())); }
-
Is it just informational or is there a question related ?
-
@SGaist, Informational