how to set a value for the listwidget item? - qt

I create A list widget in which I add items...my items are the filenames. Is any way to store the filepaths of this filenames? I want to know how to set a specific value to an item in the listwidget?

You can use:
ListWidgetItem::setData(int role,Qvariant data);
to store your filePath;
like this:
QString fileName = "hello.txt";
QString filePath = "/home/user/hello.txt";
//Adding to listWidget
QListWidgetItem *item =new QListWidgetItem();
item->setText(fileName);
item->setData(1,filePath);//here role is set as 1
listWidget->addItem(item);
//For taking back that filePath
QString filePath = listWidget->currentItem()->data(1); //note::: role equals 1

Related

How to set data source for a list view to contain custom data ? (and associate with QTableView)

I am trying to get listview and tableview working together.
The listview must be used for display, the tableview must be used for editing data. The tableview is created on demand in a popup widget (and it may never be needed).
I populate the listview, on start, from a text file - each row a line, with 2 entries separated by a tab. Easy.
The tableview will have to edit 2 columns separately... also, on listview click, I must be able to retrieve the first part of the split...
I have created a model subclass of QStringListModel.
QListView *m_myView = new QListView();
StringList *m_myList = new StringList();
QTextStream in(&myFile);
while (!in.atEnd())
{
QString temp = in.readLine();
if(!temp.isEmpty())
m_myList->append(temp);
}
myFile.close();
m_myView->setModel(m_myList);
where
class StringList : public QStringListModel
{
public:
void append (const QString& string)
{
insertRows(rowCount(), 1);
QModelIndex m = index(rowCount() - 1);
setData(m, string, Qt::EditRole);
QStringList splist = string.split('\t');
setData(m, splist.at(0), Qt::ToolTipRole);
if(splist.size() > 1)
setData(m, splist.at(1), Qt::StatusTipRole);
else
setData(m, "", Qt::StatusTipRole);
qDebug() << data(m, Qt::EditRole).toString()
<< data(m, Qt::ToolTipRole).toString()
<< data(m, Qt::StatusTipRole).toString();
}
};
The EditRole displays correctly, the others display empty strings.
It seems that QStringListModel is incapable of storing anything except EditRole.
So I am left with 2 options - either do the split on each selection, and also when creating the table view, or - what I would like to try but don't know how - create a QStandardItemModel that can act as data sources for both the listview and the tableview, and can easily retrieve the partial data I require on click.
I thought I can simply use it to set the data on listview (like they do here).
QListView *m_myView = new QListView();
QStandardItemModel *m_myList = new QStandardItemModel();
QTextStream in(&myFile);
int r = 0;
while (!in.atEnd())
{
QString temp = in.readLine();
if(!temp.isEmpty())
{
QStringList splist = temp.split('\t'); // assume I know there will be 2 strings always
QStandardItem *item = new QStandardItem(splist.at(0));
m_myList->setItem(r, 0, item);
QStandardItem *item1 = new QStandardItem(splist.at(1));
m_myList->setItem(r, 1, item1);
++r;
}
}
myFile.close();
m_myView->setModel(m_myList);
connect(m_myListView, SIGNAL(clicked(QModelIndex)),
this, SLOT(listChangedSlot(QModelIndex)));
But this will only set the first string in the listview, I really need both, and I still don't know how to retrieve the data
void listChangedSlot(QModelIndex index)
{
qDebug() << m_myList->item(index.row(), 0)->data().toString()
<< m_myList->item(index.row(), 1)->data().toString();
} // shows empty strings
Or...
In the loading section, try:
if(!temp.isEmpty())
{
QStringList splist = temp.split('\t');
splist.append(QString()); // so I don't need to test
QStandardItem *item = new QStandardItem(temp);
m_myList->setItem(r, 0, item);
QModelIndex idx = m_myList->index(r, 0);
QMap<int, QVariant> roles;
roles.insert(Qt::UserRole + 1, QVariant(splist.at(0)));
roles.insert(Qt::UserRole + 2, QVariant(splist.at(1)));
roles.insert(Qt::DisplayRole, QVariant(temp));
m_myList->setItemData(idx, roles);
++r;
}
This works - displays fine and gets the correct content on click - but seems to be unusable for the tableview.
(And seems I am doing twice the work, with setItem and setItemData - so technically storing the content 3 times).
How can I get my listview have a datasource with 2 string items, show both, be able to set it on a tableview, and be able to retrieve the first item on click ?
I figured out a way to share the data source between the listview and tableview:
I create 3 columns - column 0 with the combined components, and columns 1 and 2 with the separated components.
The listview will display only column 0. For tableview, I will hide column 0.
The data I require for processing will be stored in columns 1 and 2. user edit of the data in tableview will require, upon accepting changes, the edit of corresponding column 0.

Making a dynamic QMenu in QT

I have a QMenu, where I want to add QActions. The problem is, everytime the table is clicked, the existing menu adds onto itself. How do I stop it from doing that?
So when I click on the table, it should be new menus everytime.
void MainWindow::onTableClicked(const QModelIndex &index){
QAction *action;
// action->setAutoRepeat(false);
if (index.isValid()) {
QString cellText = index.data().toString();
QString indexRow = QString::number(index.row());
QString indexCol = QString::number(index.column());
ui->textBrowser->setText(indexRow + "\n"+ indexCol);
QSet<int> possiblevalues = findPossibleValues(index.row(),index.column());
for(int n : possiblevalues){
listofPossibleValues.push_back(QString::number(n));
}
for(auto s :listofPossibleValues){
action = myMenu.addAction("Set Value "+s);
}
}
}
The reason why it looked like myMenu.clear wasnt working was because i did not remove listofPossibleValues after I added the menuaction. I was able to fix it by adding
//At the beginning
myMenu.clear();
//At the end
listofPossibleValues.clear();

Config file gets overwritten in qt

I am writing data to a config file using the following code.
QSettings settings("/root/configFile.ini",QSettings::IniFormat);
QString userName = lineEditUsername.text();
QString password = lineEditPassword.text();
QList<QString> listUsername;
QList<QString> listPassword;
settings.beginWriteArray("UserData");
for(i=0;i<listUsername.size();i++)
{
Qstring user = listUsername.at(i);
Qstring pass = listPassword.at(i);
settings.setArryIndex(i);
settings.setValue("Username",user);
settings.setValue("Password",pass);
}
settings.endArray();
}
Now when I run the code first time and give 4 or 5 values they are formed in proper order in the file. However if I run the application for second time the values start overwriting from first position. Can some one suggest me some solution for this?
Instead of creating and maintaining arrays and indexes, I would propose to create user credentials map and store it in the settings file as follows:
QSettings settings("/root/configFile.ini", QSettings::IniFormat);
QString userName = lineEditUsername.text();
QString password = lineEditPassword.text();
QList<QString> listUsername;
QList<QString> listPassword;
//settings.beginWriteArray("UserData");
QVariantMap userDataMapping;
for(int i = 0; i < listUsername.size() ; i++)
{
QString user = listUsername.at(i);
QString pass = listPassword.at(i);
userDataMapping[user] = pass;
//settings.setArryIndex(i);
//settings.setValue("Username",user);
//settings.setValue("Password",pass);
}
// Store the mapping.
settings.setValue("UserData", userDataMapping);
//settings.endArray();
// ...
This will store your data in ini file in the following format:
UserData=#Variant(\0\0\0\b\0\0\0\x1\0\0\0\x6\0\x64\0\x64\0\x64\0\0\0\n\0\0\0\x6\0\x62\0\x62\0\x62)
When you read settings, do something like this:
[..]
QVariant v = settings.value("UserData");
QVariantMap map = v.value<QVariantMap>();
QMapIterator<QString, QVariant> i(map);
while (i.hasNext()) {
i.next();
QString user = i.key();
QString pass = i.value().toString();
}
You need to retrieve the amount of existing entries before adding a new one. Something like this:
int size = settings.beginReadArray( "UserData" );
settings.endArray();
settings.beginWriteArray( "UserData" );
settings.setArrayIndex( size ); // Note: Maybe 'size - 1', not sure
// ...
settings.endArray();
setArrayIndex( size ) will move the array index to the end and will thus no longer override an existing entry

Filling some QTableWidgetItems with QString from file

I'm trying to fill a QTableWidget from a file that was exported by my program, but when I try to set text to the table cells they just ignore me, nothing happens.
void MainWindow::on_actionOpen_Project_triggered()
{
QString line, fileName;
fileName = QFileDialog::getOpenFileName(this,tr("Open Project"), "", tr("Project Files (*.project)"));
if(!fileName.isEmpty()){
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
QTextStream in(&file);
for(int i=0;i<ui->code->rowCount();i++){ // goes through table rows
for(int j=0;j<ui->code->columnCount();j++){ // through table columns
ui->code->setCurrentCell(i,j);
QTableWidgetItem *cell = ui->code->currentItem();
in >> line;
if(!line.isEmpty()){
cell = new QTableWidgetItem(line); // relates the pointer to a new object, because the table is empty.
ui->errorlog->append(line); // just for checking if the string is correct visually.
}
}
}
file.close();
}
}
The errorlog object shows on the screen the correct values opened from the file, however the table is not filled. Any problems found?
This line:
cell = new QTableWidgetItem(line);
doesn't do what you think it does. Assigning the cell doesn't change anything in the table – cell is just a local variable, overwriting it doesn't have any effect elsewhere.
You (probably) want to do something like this instead:
cell->setText(line);
Or (if you don't really need to change the current item):
ui->code->item(i,j)->setText(line);
If those give you a segfault, it's that you haven't set the table's widget items yet. In that case, you should do something like:
QTableWidgetItem *cell = ui->code->item(i,j);
if (!cell) {
cell = new QTableWidgetItem;
ui->code->setItem(i,j,cell);
}
if (!line.isEmpty()) {
cell->setText(line);
}
This will populate all the cells with QTableWidgetItems the first time this function is called, and reuse them subsequently.

How to get the texts of all items from QListWidget in Qt?

How can I get the texts of all the widgets in a QListWidget as a QList<QString>?
I can get the list of widget items like this:
QList<QListWidgetItem *> items =
ui->listWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard);
But that's not exactly what I want, I'd like the list of the widget text() properties.
There is no built-in function for that, you'll need to do it manually.
QList<QString> texts;
foreach(QListWidgetItem *item, items)
texts.append(item->text());
Or something like that.
int c = ui->listWidget->count();
for (int i = 0; i < c ; ++i){
QString s = QString::number(i);
QModelIndex *model_index = new QModelIndex(ui->listWidget->model()->index(i,0) ); //0th column since we have one cloumn in listwidget
QString q= model_index->data(Qt::DisplayRole).toString();
qDebug()<<q;
}

Resources