QT C++ Framework QlistwidgetItem CONVERSION - c++

I have a list you can fill it on your own with QfileDialog and put the selected files in a widgetList.
I can access the list and colour all those items and do whatever I want to, except this one problem:
I would like to select one item from the list and convert it somehow to QStringList so I can use it as a Phonon MediaSource.
I don't know how I can extract this item, I want the text shown in ListWidget and put it in my mediaObj so I can play it.
Here is a little bit of my code:
How i open the FileDialog (works):
QStringList fileNames;
QFileDialog fDialog(this);
fDialog.setFileMode(QFileDialog::AnyFile);
fDialog.setNameFilter(tr("Music(*.mp3)"));
fDialog.setViewMode(QFileDialog::Detail);
while (true) {
if (fDialog.exec()) {
fileNames = fDialog.selectedFiles();
widget.list->addItems(fileNames);
musicObj->enqueue(fileNames.last());
} else {
break;
}
}
How I access one item clicked in the list:
QListWidgetItem *list_itm = widget.list->currentItem();
list_itm->setTextColor(Qt::red);
But I can extract the string shown on my cursor position.

QListWidgetItem *list_itm = widget.list->currentItem();
list_itm->setTextColor(Qt::red);
QStringList list;
list << list_itm.text();
Unless I've misunderstood, you just want a QStringList with a single item in, the current widget item.

Related

QListWidget Remove selected Item and its settings QT

I need help creating a function for deleting items from a QListWidget. I need to copy the name of the last item in the list, remove settings from .ini then remove from from QListWidget. So far all I can find is to how to use QList to delete the selected item.
My add function looks like:
void Edge::on_slotNew_pressed()
{
int i = ui->slotList->count();
i++;
QString slotNumber = "Slot" + QString::number(i);
ui->slotList->addItem(slotNumber);
QSettings settings("config.ini",QSettings::IniFormat);
qDebug() << settings.fileName();
settings.beginGroup(slotNumber);
settings.setValue("slotSizeW", m_prefs.slotSizeW);
settings.setValue("slotSizeH", m_prefs.slotSizeH);
settings.setValue("slotPosX", m_prefs.slotPosX);
settings.setValue("slotPosY", m_prefs.slotPosY);
settings.setValue("slotMax", m_prefs.slotMax);
settings.setValue("slotPriority", m_prefs.slotPriority);
settings.setValue("slotBorderless", m_prefs.slotBorderless);
settings.setValue("slotHotkey", m_prefs.slotHotkey);
settings.endGroup();
qDebug() << slotNumber;
}
**EDIT:**Updated Remove function
Currently my remove function looks like
void Edge::on_slotDelete_clicked()
{
QSettings settings("slots.ini",QSettings::IniFormat);
int i = ui->slotList->count();
QString slotNumber = "Slot" + QString::number(i);
QList<QListWidgetItem*> items = ui->slotList->selectedItems();
foreach(QListWidgetItem* item, items)
{
ui->slotList->removeItemWidget(item);
delete item;
}
settings.beginGroup(slotNumber);
settings.remove("");
settings.endGroup();
qDebug() << settings.fileName();
}
I derped and forgot to update the config name so removal works, I just possibly need a better naming convention as it has to be passed as a QString, QListWidgetItem* will not pass correctly
To delete a group and his content call:
settings.beginGroup(item->getSlotNumber()); // please use here the correct method to get the SlotNumber
settings.remove(""); //removes the group, and all it keys
settings.endGroup();
To get the last name of ui->slotList use the count()-method or the last()-method to get the last item of slotItems:
ui->slotList->item(ui->slotList->count() - 1); // or
ui->slotList->last()
The final answer was to use
void Edge::on_slotDelete_clicked()
{
QSettings settings("slots.ini",QSettings::IniFormat);
QString slotText;
QList<QListWidgetItem*> items = ui->slotList->selectedItems();
foreach(QListWidgetItem* item, items)
{
ui->slotList->removeItemWidget(item);
slotText.append(item->text());//this grabs the name
delete item;// this deletes list item
}
settings.beginGroup(slotText);// only takes QString or const QString argument
settings.remove("");
settings.endGroup();
qDebug() << slotText;
}
And that is how you can delete a selected item and its settings! Not quite what I was looking for but it changes the burden to having a proper naming convention on the save portion. Thank you for all of the support, you pushed me to finding the answer!

Qt5 : Get value of item clicked in a listview

I'm making a Qt5.7 application where I am populating a QListView after reading stuff from a file. Here's the exact code of it.
QStringListModel *model;
model = new QStringListModel(this);
model->setStringList(stringList); //stringList has a list of strings
ui->listView->setModel(model);
ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers); //To disable editing
Now this displays the list just fine in a QListView that I have set up. What I need to do now is to get the string that has been double clicked and use that value elsewhere. How do I achieve that?
What I tried doing was to attach a listener to the QListView this way
... // the rest of the code
connect(ui->listView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(fetch()));
...
And then I have the function fetch
void Window::fetch () {
qDebug() << "Something was clicked!";
QObject *s = sender();
qDebug() << s->objectName();
}
However the objectName() function returns "listView" and not the listView item or the index.
The signal already provides you with a QModelIndex which was clicked.
So you should change your slot to this:
void Window::fetch (QModelIndex index)
{
....
QModelIndex has now a column and a row property. Because a list has no columns you are interessted in the row. This is the index of the item clicked.
//get model and cast to QStringListModel
QStringListModel* listModel= qobject_cast<QStringListModel*>(ui->listView->model());
//get value at row()
QString value = listModel->stringList().at(index.row());
You should add the index as parameter of your slot. You can use that index to access the list
Your code should be some thing like this.
void Window::fetch (QModelIndex index) {
/* Do some thing you want to do*/
}

Getting variable from widget in a QListWidget

I have a custom QWidget class called VideoWidget. Its source file looks something like this:
VideoWidget::VideoWidget(QWidget *parent, string test) :
QWidget(parent)
{
pathname=test;
QLabel *label= new QLabel(pathname.c_str(), this);
//...
}
string VideoWidget::getFilePath(){
return pathname;
}
In my MainWindow class I add the VideoWidget to a QListWidget through looping through a xml file and getting the string argument from that file like this:
QDomNode node = rootXML.firstChild();
while( !node.isNull() )
{
if( node.isElement() )
{
QDomElement element = node.toElement();
VideoWidget* mytest = new VideoWidget(this, element.attribute( "Pathname", "not set").toStdString());
QListWidgetItem* item = new QListWidgetItem;
item->setSizeHint(QSize(150,100));
ui->myList->addItem(item);
ui->myList->setItemWidget(item,mytest);
}
node = node.nextSibling();
}
This correctly fills my QListWidget with the VideoWidget where all the labels have a different value.
Now I'd like to get the pathname variable everytime I doubleclick on a item in the QListWidget like this:
connect(ui->myList,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(playClip(QModelIndex)));
void MainWindow::playClip(QModelIndex index){
QListWidgetItem* item = ui->myList->itemAt(0,index.row());
VideoWidget* widget = dynamic_cast<VideoWidget*>(ui->myList->itemWidget(item));
cout << widget->getFilePath() << endl;
}
My problem is that widget->getFilePath() always returns the same value for every clicked widget. It is the value of the first time I set pathname=test;. What am I missing here?
This is probably mistake:
QListWidgetItem* item = ui->myList->itemAt(0,index.row());
Method "itemAt" takes x and y coordinates, not indexes. Use "takeItem" instead.
Next thing I want to say is that this part:
ui->myList->itemWidget(item)
is useless. You can convert "item" directly.
And last - use qobject_cast since you use Qt. And never use dynamic_case (especially when you anyway do not check result against NULL).

Hide the checkbox from a QListView item

I wave a QListView that is backed by a QStandardItemModel. Under certain circonstances, the QStandardItem are made checkable. A checkbox gets displayed besides the item's display. At some point, I want to remove hide the QStandardItem checkbox. I set its checkable state to false but it doesn't hide the checkbox (though it cannot be checked anymore).
The only way I have found of hiding the checkbox is to replace the item with a new one. This doesn't seem the proper way to preceed.
This is the code:
MyModel::MyModel(QObject *parent):QStandardItemModel(parent){}
void MyModel::createItem(int row, const QString &text)
{
setItem(row, new QStandardItem(text));
}
void MyModel::setCheckable(int row)
{
item(row)->setCheckState(Qt::Unchecked);
item(row)->setCheckable(true); // A checkbox appears besides the text
}
void MyModel::hideCheckBox(int row)
{
item(row)->setCheckState(Qt::Unchecked);
item(row)->setCheckable(false); // does not work
// I need to completely replace the item for the checkbox to disapear.
// This doesn't seem the proper way to proceed
setItem(row, new QStandardItem(item(row)->data(Qt::DisplayRole).toString()));
}
Is there better way to proceed?
When you call setCheckState or setCheckable, the qt will update the data of list item by adding or setting a Qt::CheckStateRole data. If the Qt::CheckStateRole data is existed, the check icon will be shown. So you need remove it from the data map of the list item.
Finally, the code of hideCheckBox should be:
void MyModel::hideCheckBox(int row)
{
// check the item pointer
QStandardItem* pitem = item(row);
if (pitem == NULL) return;
// find and delete the Qt::CheckStateRole data
QMap<int, QVariant> mdata = itemData(pitem->index());
if (mdata.remove(Qt::CheckStateRole))
{
setItemData(pitem->index(), mdata);
}
}
Hope it useful. :)
I think the presence of the check boxes in items defined by item flags, so that I would write the function in the following way:
void MyModel::hideCheckBox(int row)
{
// Does not set the Qt::ItemIsUserCheckable flag.
item(row)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
}

How to add a QString to a QListView using a QLineEdit

I want to use a QLineEdit to write a QString, then using a QPushButton, I want to add an item (a string) to a listView
Here is what I got:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
model = new QStringListModel(this);
QStringList list;
list << "Some Item";
model->setStringList(list);
ui->listView->setModel(model);
ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
void MainWindow::on_pushButton_3_clicked()
{
//add
int row = model->rowCount(); // model = new QStringListModel
model->insertRow(row);
QModelIndex index = model->index(row);
ui->listView->setCurrentIndex(index);
ui->listView->edit(index); // instead of edit, I'd like to ... add a QString
}
Problem is I don't want to be able to edit (this was all I was manage to do by myself). I want now to instead add an item at CurrentIndex, and that item to be the text field of lineEdit. How do I get access to that field ? is it lineEdit->text() ? and how do I add that to the list view ?
I simply do not know how to add anything to a list. I found edit by mistake, and google has not helped so far. I'm hoping Stack Overflow can, and will.
EDIT: I have decided to try this, but it doesn't seem to be the best solution
void MainWindow::on_pushButton_3_clicked()
{
//add
QStringList list;
list = model->stringList();
list.append(ui->lineEdit->text());
model->setStringList(list);
}
But this seems to be an odd way of doing things. Also it seems to include a newline for some reason.
There is already an example of how to use a QStringListModel here: https://stackoverflow.com/a/5825113/496445
model->insertRow(model->rowCount());
QModelIndex index = model->index(model->rowCount()-1)
model->setData(index, str);
Note that in this suggested approach, you do not need the QStringList, unless you already had one for another reason and want to initialize with it.
When you use a Q*View instead of a Widget, you will be dealing with the model directly for data instead of the view. The view will be notified when the model changes. In this case, you would probably be accessing your lineEdit like this:
QString str = ui->lineEdit->text();
Another way; right-click to listView and select "morph into" -> "QListWidget"
At this time you can see this function "lst->addItem("str");"