I create combobox

QSqlTableModel *comboModel = model->relationModel(10); ui->workComboBox->setModel(comboModel); ui->workComboBox->setModelColumn(comboModel->fieldIndex("name")); 

when selecting data must filter the model

  void MainWindow::on_workComboBox_currentIndexChanged(const QString &arg1) { qDebug() << "worker selected = " << arg1; qDebug() << clickedDay; model->setFilter(QString( "name = '%1' and exec_date = '%2'") .arg(arg1) .arg(clickedDay)); model->select(); } 

When you start the program immediately filters for an incomprehensible value.

worker selected = "1" ""

How can I set the default to select ALL fields from the combobox (from the base). Or that it only works when I select something in the combo box.

  • Try filling out the combobox first: ui->workComboBox->setModel(comboModel); and only then connect his currentIndexChanged(const QString&) signal to your on_workComboBox_currentIndexChanged(const QString &arg1) slot on_workComboBox_currentIndexChanged(const QString &arg1) . - aleks.andr

2 answers 2

The connection of the drop-down list with the slot is certainly made in the designer. This conclusion can be made at least by the characteristic name of the slot. Accordingly, the relationship of the change in the current index in the list is established before the list itself receives the data set.

What's happening?

Model is created:

 QSqlTableModel *comboModel = model->relationModel(10); 

The model connects to the list widget. This automatically activates sending a signal about a change in the index of the current row:

 ui->workComboBox->setModel(comboModel); 

Since at the time of sending the signal, the modelColumn list property is set to 0 by default, the value contained in the cell of the first row and the first column is sent to the connected slot (numbering, of course, is done from scratch).

Finally, the model column shown in the list is set:

 ui->workComboBox->setModelColumn(comboModel->fieldIndex("name")); 

Here, a signal about changing the current index of the row is not sent.

How to win?

If you do not want to connect the signal to the slot after filling the list with data from the model, you can do so.

 QSqlTableModel *comboModel = model->relationModel(10); ui->workComboBox->blockSignals(true); ui->workComboBox->setModel(comboModel); ui->workComboBox->setModelColumn(comboModel->fieldIndex("name")); ui->workComboBox->blockSignals(false); ui->workComboBox->setCurrentIndex(0); 

What is wrong with the slot?

The slot accepts a string as an argument, which is then converted to a database query filter. What happens if the table stores the same string values, but under different identifiers?

For example, if a table contains names, then two "Ivan Ivanovitch" is not such a rare case. If the table contains the names of settlements, then the situation is even more complete coincidence.

It should also be remembered that string comparison is always slower than comparison of numbers, and if the table contains a large number of records, then performance is probably quite significant. However, this detail is a special case.

How else?

You can use the index of the current line, not its value. Suppose there is a table of workers ' workers :

 worker_id - INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT name - TEXT 

Then the slot can be rewritten to something else:

 void MainWindow::on_workComboBox_currentIndexChanged(int row) { QSqlTableModel *model = qobject_cast<QSqlTableModel*>(ui ->workComboBox->model()); if(model == Q_NULLPTR) return; if(row >= 0) { // Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ индСкс строки ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ - // это Π½Π΅ ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎΠΆΠ΅, Π° Π·Π½Π°Ρ‡ΠΈΡ‚ ΠΈΠ· ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ // Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π²Ρ‚ΠΎΡ€ΠΎΠ΅. const int worker_id_col = model->fieldIndex("worker_id"); const int name_col = model->fieldIndex("name"); const int worker_id = model->data(model->index(row,worker_id_col)).toInt(); const QString name = model->data(model->index(row,name_col)).toString(); qDebug() << "worker selected = " << name; model->setFilter(QString("worker_id = %1").arg(worker_id)); } else model->setFilter(QString()); model->select(); } 

    aha thanks. helped. Made slots and signals manually and not through Designer.

     connect(ui->ComboWorkersBox,SIGNAL(currentIndexChanged(const QString&)),this,SLOT(slot_comboWorkersBox_currentIndexChanged(QString))); void MainWindow::slot_comboWorkersBox_currentIndexChanged(const QString &arg1) { qDebug() << "worker selected = " << arg1; if(clickedDay=="") { clickedDay = QDate::currentDate().toString("yyyy-MM-dd"); } qDebug() << clickedDay; model->setFilter(QString( "name = '%1' and exec_date = '%2'") .arg(arg1) .arg(clickedDay)); model->select(); }