Insert Items dynamically in a QListWidget - c++

What I would like to do is taking input from a sql database and put all these datas in a QListWidget, but I don't know how many of them there gonna be, I need also to know the id of which one was clicked when clicked.
Any ideas?

if str is the label from your sql query and n is the id then:
create your items with:
QListWidgetItem* i = new QListWidgetItem(str);
Set the id with:
i->setData(Qt::UserRole, n);
and add it to the widget:
myListWidget->addItem(i);
Then when its clicked you will get the signal
void QListWidget::itemActivated ( QListWidgetItem * item ) [signal]
connect this to a slot in your class and get the id back with
item->data(Qt::UserRole).toInt();
But this is also a good time to use QTableView and QSqlQueryModel.

Related

Transfer a list from a foreign key to an external combobox

Initially, I used qsqlrelationtablemodel in my database project. And the values were entered into the database using the combobox inside the tableView. And it looked something like this:
enter image description here
And the code looked very simple:
model->setTable(sql_query);
model->setRelation(1, QSqlRelation("my_schema.aircrafts","id_aircraft","registration_number"));
model->setRelation(3, QSqlRelation("my_schema.airports","id_airport","name_airport"));
model->setRelation(4, QSqlRelation("my_schema.airports","id_airport","name_airport"));
ui->tableView->setModel(model);
ui->tableView->setItemDelegateForColumn(1, new QSqlRelationalDelegate(this));
ui->tableView->setItemDelegateForColumn(3, new QSqlRelationalDelegate(this));
ui->tableView->setItemDelegateForColumn(4, new QSqlRelationalDelegate(this));
But now I have redone the data entry on the forms and there are no problems with transferring information to qlineedit. There are difficulties with transferring data from foreign key's to an external combobox.
Now it looks like this (the value of the combobox does not change when you click on another row of the tableView):
enter image description here
Now I'm using this code, but I don't understand how to pass the value of the selected index in the tableView to the combobox.
QString query = QString("SELECT * FROM my_schema.route WHERE id_route = '%1'").arg(id);
QSqlQuery qw;
qw.exec(query);
while(qw.next())
{
ui->lineEdit->setText(qw.value(1).toString());
ui->lineEdit_2->setText(qw.value(2).toString());
ui->lineEdit_3->setText(qw.value(3).toString());
ui->comboBox_2->setModel(model);
ui->comboBox_2->setModelColumn(4);
}
I would like to see something like this result:
enter image description here
Please tell me in the most accessible form how to achieve this
You have model and tableview for fetching all columns for clicked row by using QAbstractItemView::clicked(const QModelIndex &index) signal for receive event. And implement the slot that loops all columns in selected row like this example snippet:
// create query with join for combobox model only containing desired values not foreign keys
// after that create QStringList and fill it with query result
// set stringlistmodel to combobox
ui->comboBox_2->setModel(stringlistmodel); // this is different from tableview's model
connect(ui->tableView, &QTableView::clicked, [this](const QModelIndex &index)
{
auto row{index.row()};
ui->lineEdit->setText(model.data(model.index(row, 0).toString());
//...
ui->comboBox_2->setCurrentIndex(model.data(model.index(row, 4).toInt());
//...
});

Add QTableView to QComboBox

I'm retrieving a set of results from the database and I want to populate the QComboBox with the resulting columns from the database (each row of the QComboBox should have the same columns as database result) and after that I would like to be able to retrieve from one row of the QComboBox a specific column and use it further in the app. I'm thinking if it would be possible to add the QTableView to QComboBox. I'm want to do this because I want to add more meaning to the results in a way that some result columns are just plain numbers and other are the description information.
I found out that it would be possible to concatenate the result and populate the QComboBox but this will leave me with only one value for each row to work with and I have to explode the string to obtain the exact part that it is needed to work with.
The popup that comes by default is a QListView, this can be changed with any object that inherits from QAbstractItemView, and in this case a QTableView will be used for it to use the setView() method, the result when clicking only should return a item of the selected row, then to set the column to be displayed after being selected will use the method setModelColumn() indicating the position of the column, but before that the model is set to the QComboBox using the method setModel().
# my model
model = new QSqlTableModel;
model->setTable("person");
model->select();
# setModel
comboBox->setModel(model);
# select column
comboBox->setModelColumn(1);
QTableView *view = new QTableView(this);
comboBox->setView(view);
Note: The model is set to QComboBox, not to QTableView. Also you could have problems with the width of QTableView, so we must resize, in my case use the following:
view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
view->setMinimumWidth(500);
The complete example can be found in the following link

How to identify QStandardItem's in a QListView without using the text field?

I'm trying to identify objects in my QListView item model. I'm currently using the text field of the list view which is obviously not the best idea.
This is my minimal code to fill the widget, see how I save a timestamp to the text field:
QListView * view = new QListView(this);
QStandardItemModel * model = new QStandardItemModel(this);
MyElements * mylist = getElements();
while (!mylist->isFirst())
{
QStandardItem * item = new QStandardItem(mylist->getIcon(), mylist->getTimeString());
model->appendRow(item);
mylist = mylist->getPrevious();
}
view->setModel(model);
As you can see I have a unique timestamp for each item storing the unix time in milliseconds as a string. I can use this to identify my objects and this way I can always be sure which item is clicked.
Now, I wish to override the text with a more userfriendly string, like "Click this to do stuff" and not displaying the timestamp anymore.
But I still need the timestamp to identify each unique item in the list. Any idea where else I could store this data?
You can use the QStandardItem::setData() function to set any kind of data to the item. For example:
QStandardItem * item = new QStandardItem(list->getIcon(), "some text");
item->setData(list->getTimeString());
// ...
In order to get this data you will need to:
QString d = item->data().toString();
You can use custom roles to store multiple data sets in an item using Qt::UserRole.

connect QTreeWidgetItem to database

Im working on a project where im trying to build a QTreeWidget that has multiple QTreeWidgetItems
and once i click on a particular item it connects to a database and shows a query result in a tableview model, until now every thing works fine.
the problem is that i want each item to output different resut depending on some criteria on the same table where this criteria is only changing the value of an attribute, and this value is the same of the item name. for example item named 122 and the table has atribute called no. when we click on item 122 the result of this query must be shown (select * from table where no=122)
any help :)
I am assuming you have a QTableView backed by a QSqlQueryModel or QSqlTableModel.
You can connect to the signal QTreeWidget::itemSelectionChanged() and then in the slot you get the current item with selectedItems()[0]. Then you create your query:
QSqlQuery query;
query.prepare("select * from table where no=:no");
query.bindValue(":no", number);
query.exec();
Finally you can use setQuery (const QSqlQuery & query) on the model. This should update your view.
I hope I understood correctly what you want to achieve.

How to check which item from menu was chosen? How to send int/wxstring with choosing menu item?

I've got menu in which i need to place dynamically few items( i don't know how many until app launch;-). It's not problem to put item in menu, and connect it`s event to some function. But i need to check which item from menu was chosen. Can i send int or wxString with click at menu item? How?
wxMenu *MyTaskBarIcon::CreatePopupMenu(){
wxMenu *menu = new wxMenu;
menu->Append(ITEM1, _("Item1"));
Connect(ITEM1,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyTaskBarIcon::Check));
menu->Append(ITEM2, _("Item2"));
Connect(ITEM2,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyTaskBarIcon::CheckMenu));
menu->AppendSeparator();
menu->Append(PU_EXIT, wxT("E&xit"));
}
void MyTaskBarIcon::Check(wxCommandEvent& event){
//How to send int/wxString to this method?
}
Any ideas?
How about assigning a range of IDs to this menu? Then when you append the items to the menu, you can increment the ID each time, so each item gets a unique ID. Then you create an event handler for each ID, and call a common handler with the ID as a parameter. Or, you could use
wxEvent::GetId()
If the strings vary at runtime then you will have to store the strings in an array, and recall them from there using the ID minus the start of the range ID as the index into the array.
Use GetString() to see what the user selected:
wxString GetString () const
Returns item string for a listbox or choice selection event.