Is there a way to print the data of a QstandardItem out, say I have;
QList<QStandardItem*> testQList;
QString yay = "!Yay";
QStandardItem *item = new QStandardItem(yay);
testQList.append(item);
qDebug() << testQList;
I just get the memory addres, (0x409bd00) I cannot dereference the list either.
You get this because you try to print whole list with objects, it is not list with strings. In this case qDebug always prints memory address so you should use loop and text() method(iterate throw list).
for(int i = 0; i<testQList.size();i++)
{
qDebug() << testQList.at(i)->text();
}
#include <QCoreApplication>
#include <QString>
#include <QList>
#include <QDebug>
class QStandardItem
{
QString mStr;
public:
QStandardItem(QString str)
{
mStr = str;
}
QString toString()
{
return mStr;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QList<QStandardItem*> testQList;
QString yay = "!Yay";
QStandardItem *item = new QStandardItem(yay);
testQList.append(item);
for(int i = 0; i<testQList.size();i++)
{
qDebug() << testQList.at(i)->toString();
}
return a.exec();
}
Related
I have a treeview which is modeling a file tree. Each item in the TreeView is a QstandardItem that holds a file path. I would like to be able to get the file it referres to and drag the item into another application. The files are all video files so I would like to add the ability to drag and drop into VLC, Adobe Premier etc.
minialistic code :
main.cpp
drag d:/1.txt drop to notepad
#include <QtWidgets/QApplication>
#include <QMimeData>
#include <QTreeView>
#include <QDrag>
#include <QStandardItemModel>
#include<QUrl>
class Myodel :public QStandardItemModel
{
Q_OBJECT
public:
QStringList mimeTypes() const override
{
return QStringList(QLatin1String("text/uri-list"));
}
QMimeData* mimeData(const QModelIndexList& indexes) const override
{
QList<QUrl> urls;
QList<QModelIndex>::const_iterator it = indexes.begin();
for (; it != indexes.end(); ++it)
if ((*it).column() == 0)
urls << QUrl::fromLocalFile("d:/1.txt");
QMimeData* data = new QMimeData();
data->setUrls(urls);
return data;
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Myodel* model = new Myodel;
QStandardItem* parentItem = model->invisibleRootItem();
for (int i = 0; i < 4; ++i) {
QStandardItem* item = new QStandardItem(QString("item %0").arg(i));
parentItem->appendRow(item);
parentItem = item;
}
QTreeView* tree = new QTreeView();
tree->setModel(model);
tree->setDragEnabled(true);
tree->show();
return a.exec();
}
#include"main.moc"
I managed to write the data to the objects from the file. But I can't output this data to the console.
I already wrote-ListtForLoad.first().getName()
But can't get such access
I attach the full code of my program.
#include <QCoreApplication>
#include <QFile>
#include <QString>
#include <QDebug>
#include <QIODevice>
#include <QLinkedList>
#include <QTextStream>
class items : public QObject {
public:
items(QString name, QString gryp){
this->name = name;
this->gryp = gryp;
};
QString getName() {
return name;
}
QString getGryp() {
return gryp;
}
private:
QString name;
QString gryp;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QLinkedList<QObject*> ListtForLoad;
QFile fileIn("myfile.txt");
QFile fileOut("myfileout.txt");
int lineCount = 0;
if (fileIn.open(QIODevice::ReadOnly | QIODevice::Text)){
lineCount = QTextStream(&fileIn).readAll().split('\n').count();
fileIn.close();
}
QString stringAllRead;
if(fileIn.open(QIODevice::ReadOnly)) {
stringAllRead = fileIn.readAll();
QStringList splitLines = stringAllRead.split("\r\n");
for (int countItems = 0; countItems < lineCount; countItems++) {
QStringList people = splitLines[countItems].split("&");
ListtForLoad << new items( people[0], people[1] );
}
qDebug() << ListtForLoad.first().getName();
fileOut.close();
}
return a.exec();
}
You are storing QObject*'s in the QLinkedList so when you do the below, you get a QObject* back:
ListtForLoad.first() // <- QObject* here
.getName()
To derefernce a pointer, you need to use -> instead of . so:
ListtForLoad.first()->getName();
However, QObject doesn't have a getName() member function.
You should probably store your own type (items) in the list instead:
QLinkedList<items*> ListtForLoad;
I am wondering how I would foreach through a QJsonObject to get the key/value pairs in C++? So far, I am only able to get the value.
//main.cpp
QFile file(":/geoip.json");
file.open(QIODevice::ReadOnly);
QByteArray rawData = file.readAll();
file.close();
QJsonDocument doc(QJsonDocument::fromJson(rawData));
QJsonObject json = doc.object();
foreach(const QJsonValue &value, json) {
QJsonObject obj = value.toObject();
qDebug() << value;
}
//geoip.json
{
"Afghanistan": "58.147.159.255",
"Albania": "31.22.63.255",
"Algeria": "105.235.143.255",
"American Samoa": "202.70.115.241",
"Andorra": "109.111.127.255",
"Angola": "105.175.255.255",
"Anguilla": "208.66.50.44",
"Antarctica": "46.36.195.10"
}
John already gave the answer. Using keys() a complete working solution would be:
#include <QCoreApplication>
#include <QFile>
#include <QByteArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//main.cpp
QFile file("path/to/geoip.json");
file.open(QIODevice::ReadOnly);
QByteArray rawData = file.readAll();
file.close();
QJsonDocument doc(QJsonDocument::fromJson(rawData));
QJsonObject json = doc.object();
foreach(const QString& key, json.keys()) {
QJsonValue value = json.value(key);
qDebug() << "Key = " << key << ", Value = " << value.toString();
}
return a.exec();
}
I know this post is old but to answer Nuclear
With the method proposed by Twisq it is possible to browse a JSON by obtaining the keys and values without problem.
But you are talking about iterating a JSON...?
With "QJsonObject::const_iterator" objects it is possible with the code below:
#include<QJsonDocument>
#include<QJsonObject>
#include<QFile>
int main (int nbArg, char* listArg[])
{
QFile file("my_file.json");
file.open(QIODevice::ReadOnly);
QByteArray rawData = file.readAll();
file.close();
QJsonDocument doc(QJsonDocument::fromJson(rawData));
QJsonObject myJson = doc.object();
QJsonObject::const_iterator myIterator = myJson.constBegin();
QJsonObject::const_iterator myIteratorEnd = myJson.constEnd();
do
{
qDebug() << myIterator.key();
qDebug() << myIterator.value();
myIterator++;
}
while(myIterator!=myIteratorEnd);
}
I have the following code:
filter.h
#pragma once
#include <QObject>
#include <QSortFilterProxyModel>
class FilterModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit FilterModel(QObject *parent = 0);
Q_INVOKABLE QString getText (QString text);
};
filter.cpp
#include "filter.h"
#include <QDebug>
FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent) {}
QString FilterModel::getText(QString text)
{
QString qmltext = text;
qmltext != NULL ? qDebug() << qmltext
: qDebug() << "TEXT = NULL";
return qmltext;
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "abonentstable.h"
#include "filter.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
AbonentsSqlModel *abonentsSqlModel = new AbonentsSqlModel;
abonentsSqlModel->setQuery("SELECT * FROM abonents");
FilterModel *filterModel = new FilterModel;
filterModel->setSourceModel(abonentsSqlModel);
filterModel->setFilterKeyColumn(0);
filterModel->setFilterWildcard("9");
QQmlContext *context = engine.rootContext();
context->setContextProperty("abonents", filterModel);
context->setContextProperty("filter", filterModel);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
And the .qml file part:
TextField {
id: textField
...
onTextChanged: {
filter.getText(textField.text)
}
...
}
Method getText() gets text (suddenly!) from QML TextField and prints it into debugger, it works fine. But as you can see, I have code for table sorting.
The following problem is: now sorting mask is "9", it works, but I need to return QString qmltext from getText() in some way and put it into filterModel->setFilterWildcard() in main.cpp like that:
QString qmlText = filterModel.getText(QString);
...
filterModel->setFilterWildcard(qmlText);
Of course, it's just an example, it doesn't works and I don't know how to do this.
I do not fully understand what you want to do, but I think you need something like that (if you really need the return value):
QString FilterModel::getText(const QString& text)
{
setFilterWildcard(text);
return text;
}
By the way:
qmltext != NULL
is not working. Use instead:
qmltext.isEmpty() == false
I'm pretty new to QT, and I'm trying to take a list from a text file and output it into QT with nice formatting.
I managed to get the list printed on the window, but it has to be able to be sorted.
I have the radio buttons set up right now so that one of them displays the list and the other clears the list.
The problem is that when I switch from the list to the cleared list back to the list the program segfaults and I don't understand why.
The files are here.
winelist.cpp
#include "winelist.h"
#include "ui_winelist.h"
#include <QFile>
#include <QString>
#include <QStandardItemModel>
wineList::wineList(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::wineList)
{
ui->setupUi(this);
ui->ratingButton->setChecked(true);
fillList();
model->setHorizontalHeaderItem(0, new QStandardItem(QString("Wine Name")));
model->setHorizontalHeaderItem(1, new QStandardItem(QString("Vintage")));
model->setHorizontalHeaderItem(2, new QStandardItem(QString("Rating")));
model->setHorizontalHeaderItem(3, new QStandardItem(QString("Price")));
ui->listOutput->setModel(model);
}
wineList::~wineList()
{
delete ui;
}
void wineList::on_sortButton_clicked()
{
if( ui->ratingButton->isChecked())
{
for (int i = 0; i < 100; i++) {
model->setItem(i,0,wList[i].wineName);
model->setItem(i,1,wList[i].vintage);
model->setItem(i,2,wList[i].rating);
model->setItem(i,3,wList[i].price);
}
}
else
{
for(int i = 0; i < 100; i++) {
for(int j = 0; j < 4; j++) {
model->setItem(i, j, new QStandardItem(QString("")));
}
}
}
ui->listOutput->resizeColumnsToContents();
ui->listOutput->resizeRowsToContents();
}
void wineList::fillList()
{
Wine wine;
QString line;
QStringList lineElements;
QFile wineText(":/winelist.txt");
if (wineText.open(QIODevice::ReadOnly))
{
while ((line = line.fromUtf8(wineText.readLine())) != "")
{
lineElements = line.split(";");
lineElements[0].replace("\t", "");
lineElements[1].replace("\t", "");
wine.wineName = new QStandardItem(QString(lineElements.at(0)));
wine.vintage = new QStandardItem(QString(lineElements.at(1)));
wine.rating = new QStandardItem(QString::number(lineElements.at(2).toInt()));
wine.price = new QStandardItem(QString::number(lineElements.at(3).toInt()));
wList.append(wine);
}
}
wineText.close();
}
winelist.h
#ifndef WINELIST_H
#define WINELIST_H
#include <QMainWindow>
#include <QStandardItem>
#include <QStandardItemModel>
namespace Ui {
class wineList;
}
struct Wine {
QStandardItem* wineName;
QStandardItem* vintage;
QStandardItem* rating;
QStandardItem* price;
};
class wineList : public QMainWindow
{
Q_OBJECT
public:
explicit wineList(QWidget *parent = 0);
~wineList();
private slots:
void on_sortButton_clicked();
private:
Ui::wineList *ui;
QVarLengthArray<Wine> wList;
QStandardItemModel *model = new QStandardItemModel(100, 4, this);
void fillList();
void printList(QStandardItemModel *model);
};
#endif // WINELIST_H
main.cpp
#include "winelist.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
wineList w;
w.show();
return a.exec();
}
Clicking sort the first time
Switching Radio Button and clicking sort again
Switching Radio Button back and clicking sort again
Any Help is appreciated, I am completely lost here.
In the on_sortButton_clicked you're trying to read data from a list, but not doing any range checks. Instead, you've hardcoded 100 there.
You should rewrite this:
for (int i = 0; i < 100; i++) {
model->setItem(i,0,wList[i].wineName);
to this:
for (int i = 0; i < wList.size(); i++) {
model->setItem(i,0,wList[i].wineName);
--upd---
When you initially populate your model, it takes ownership over items from wList. When you replace model items with empty ones, it deletes initial items from wList. After this your wList is no move valid, because it contains Wine structs with dangling pointers. That's why when you try to populate your model second time, it crashes.