Qt C++ vector of QFiles error - qt

I have the following:
QString themePath(":/themes/");
std::vector<QString> resourcePaths;
resourcePaths.push_back(QString("html/details.html"));
std::vector<QFile> resources;
for (std::vector<QString>::iterator it = resourcePaths.begin(); it != resourcePaths.end(); ++it) {
QString path = QString("%1%2/%3").arg(themePath, THEME, *it);
QFile resource(path);
resources.push_back(resource);
}
gives me the following error:
error: 'QFile::QFile(const QFile&)' is private.
I get the same error if I use QList instead of std::vector.
Thank you for your attention.

The problem, is that you use QFile values in the container which implicitly perform copying of items with using the copy constructor which is private member function of QFile class. The compiler tells you that. To solve this you can try to simply store QFile pointers instead.

Related

Remove first bytes from QByteArray

I want to write a function in which QByteArray is input to the function.
I want to remove some header from receive data and store it into global QByteArray.
void abc::CopyData(const QByteArray &data)
{
switch(RequestPacketCount)
{
case REQUEST_FIRST_PACKET:
{
ByteArrayData = data;
}
break;
case REQUEST_SECOND_PACKET:
case REQUEST_THIRD_PACKET:
ByteArrayData.append(data);
}
}
I want to remove 'n' no. of byte from start of 'data' and store remaining data into 'ByteArrayData'
Thanks in advance.
What you seem to want is simply copy the original array and use remove;
ByteArrayData = data;
ByteArrayData.remove(0, n); // Removes first n bytes of ByteArrayData,
// leaving data unchanged
Since a QByteArray is implicitly shared, the construction of the copy takes constant time, and the modification (deletion) is what will make the actual copy when needed.
To append efficiently, you can just use data to get to the byte array, and append the part you want. That will prevent un-necessary temporary objects. That would look something like;
ByteArrayData.append(data.data() + n, data.size() - n);
You can use QByteArray::mid:
ByteArrayData = data.mid(n);
//...
ByteArrayData.append(data.mid(n));
Adding to Joachim's answer, in C++ it's rather unfortunate that some implementation details leak into the interface, but it's still preferred for performance reasons to let the compiler do the copying by passing the argument as value. So, paraphrasing, the best solution would be:
void abc::CopyData(QByteArray data)
{
...
data.remove(0, n);
...
ByteArrayData.append(data);
}
The only place where you definitely do not want to have such arguments passed by value is a signal declaration - signals never modify their data. It's fine for a slot to do so, though:
class MyClass : public QObject {
Q_OBJECT
...
public:
// pass by const reference in signals
Q_SIGNAL void dataSource(const QByteArray &); // The only correct signal form
// pass by const reference or value in slots, depending on use
Q_SLOT void dataSink1(const QByteArray &); // Valid
Q_SLOT void dataSink2(QByteArray); // Valid as well.
};
Connecting to either slot uses the same code whether it's Qt4 or Qt5 connection style. Thus you don't have to worry about such interface changes due to leaked implementation details breaking your code.
// Qt4 - you should elide const and reference anyway
connect(src, SIGNAL(dataSource(QByteArray)), dst, SLOT(dataSink1(QByteArray));
connect(src, SIGNAL(dataSource(QByteArray)), dst, SLOT(dataSink2(QByteArray));
// Qt5
connect(src, &MyClass::dataSource, dst, &MyClass::dataSink1);
connect(src, &MyClass::dataSource, dst, &MyClass::dataSink2);

why do I get an error in this code

I have looked at several different tutorials and all the code looks the same but when I try to compile it I get two errors. They are no match for call to '(QFile) (QString&)' no match for call to '(QTextSteam) (Qfile)'. Could you please explain why? The following is part of my code if you need more just ask.
my header chunk of code
private:
QLabel *label;
QTextEdit *left;
QTextEdit *right;
QLineEdit *user;
QTextStream file;
QFile namefile;
QString name;
QString n;
my source code
n ="name.txt";
namefile(n);
if (!namefile.open(QFile::ReadOnly))
{
return;
}
file(&namefile);
name=file.readLine();
right->setText(name);
Your question seems to have more to do with C++ than with Qt. In particular, it would be worthwhile for you to look into C++ initialization lists, and how class members are constructed in general.
In any event, I am assuming that the code you've listed as "my source code" is in the constructor of a class. One option is to first re-order the private members such that they are listed in order of initialization:
private:
QString n;
QFile namefile;
QTextStream file;
QString name;
Then to initialize them in the initialization list of the class constructor:
MyClass::MyClass()
:n("name.txt")
,namefile(n)
,file(&namefile)
{
if (!namefile.open(QIODevice::ReadOnly))
{
return;
}
name = file.readLine();
// Rest of your code goes here.
}
There are other ways of accomplishing this, but I'll leave it to you to research what I've suggested above.
Just change
file.setDevice(&namefile);

Qt: Is it OK to use QString as a member in exception class

I am developing a custom exception, where I'd need a QString member. Something like:
class MyException
{
private:
const QString fDescription;
public:
MyException(QString desc);
};
MyException::MyException(QString desc) : fDescription(desc)
{}
When I try to use it:
if (isErrorEncountered)
{
MyException e(QString("Descriptive message here..."));
throw e;
}
I get a segmentation fault.
The symptoms are similar as described here:
Qt QString cloning Segmentation Fault
The SIGSEGV originates from QBasicAtomicInt::ref, coming from QString::QString(const QString &other).
It seems to me as if there is an attempt to copy an invalid QString within a copy constructor. It is my understanding, that the QString keeps a pointer to its content as long as there is a valid reference to it. If a copy of MyException instance is being made, is it not true that the temporary stack instance has not left the scope and the copy should succeed?
When I implement MyException without a QString member, everything work well.
The answer to the question is "Yes, a QString can safely be a member in an exception."
The problems which I encountered were due to the fact that the object, acting as a source of data for the fDescription, had a bug. It implemented a getter method:
class Source
{
private: QString fData;
public: QString GetData(void) { this->fData; } // There is a missing return
}
Of course, the result of this call was the random value residing on the stack at the moment and hence the SIGSEGV.
The QString behaves as expected and with a valid reference to it, there are no problems using it in the exception.
The precise point where the SIGSEGV was raised was leaving the scope of the try block, where a copy of the exception is being constructed (remember: throw by value, catch by reference). The default copy constructor tries to create a shallow copy of all members and fails on accessing the invalid QString reference.

Convert a QStandardItemModel to a QVariant

I'm trying to send a QStandardItemModel-derived object to PythonQt, but I'm a little confused on how it needs to be sent. When I was using boost::python I had several controls like boost::noncopyable to ensure I wasn't recreating this object, but sharing it with python. I also had constructs to provide a boost shared pointer to python from inside python.
class Scene : public boost::enable_shared_from_this<Scene>, public QStandardItemModel
In PythonQt, however, I'm not sure what's available. The function call takes a QVariantList for all the function parameters.
QVariant PythonQt::call(PyObject* object, const QString &callable, const QVariantList &args = QVariantList))
What I'm confused about now is how to get my object to python via a QVariant. Since its derived from QStandardItemModel, I figured it would already be register
void MyObject::someFunction(QString fileName)
{
QVariant myObjectV = qVariantFromValue(this);
// send to python
...
}
But this gives me the following error:
'qt_metatype_id' : is not a member of 'QMetaTypeId<MyObject>'
I've tried registering it after I declare my class, but this throws a different error.
class MyObject : public QStandardItemModel
{
Q_OBJECT
...
};
Q_DECLARE_METATYPE(MyObject)
QStandardItemModel::QStandardItemModel(const QStandardItemModel&) is private within this context.
I actually get the error twice--once in header where I add the Q_DECLARE_METATYPE and in another header, which has a class which always derives from QStandardItemModel but is otherwise unrelated.
Is Q_DECLARE_METATYPE even the correct way to go about converting this object to a QVariant?
BOOST_PYTHON_MODULE(scene)
{
class_("Scene");
}
Yes, by default, QVariant can take one of te following types - http://doc.qt.io/qt-4.8/qvariant.html#Type-enum - and they are not enough for your task. You should declare additional types by yourself via qmetatype system. Thus you shoud call qRegisterMetaType() function.

Qt's moc causing "undefined reference to:" error

I am working on a simple drawing widget in Qt (all of the following is within one class). In the header file, I have defined
private:
QPointF translateToCanvas (QPointF input);
and in the CPP file I have defined
QPointF translateToCanvas (QPointF input) {
return input - QPointF(CANVAS_MARGIN_X, CANVAS_MARGIN_Y);
}
Somewhere else in the code, I call this with
QPointF newPoint = translateToCanvas(anotherPoint);
Whenever I compile, it gives me the error "undefined reference to `MyClass::translateToCanvas(QPointF)'", and this is happening inside the stuff that moc's generating and not actually my literal code.
What could be causing this error in Qt? (I'm using Qt Creator with Qt 4.5.)
This has nothing to do with Qt.
QPointF translateToCanvas (QPointF input) {
return input - QPointF(CANVAS_MARGIN_X, CANVAS_MARGIN_Y);
}
defines a standalone function named translateToCanvas, which has nothing to do with the private method you declared in your class, other than happening to have the same name. You want
QPointF MyClass::translateToCanvas (QPointF input) {
return input - QPointF(CANVAS_MARGIN_X, CANVAS_MARGIN_Y);
}

Resources