QVector array in QT cannot access private member error - qt

I have experience in programming but Im still learning, I decided to create a QVector array to store some QGraphicsRectItem in it like this:
QVector<QGraphicsRectItem> *FreeLayer1;
FreeLayer1 = new QVector<QGraphicsRectItem>;
FreeLayer1->resize(10);
Here is the error:
c:\QtSDK\Desktop\Qt\4.8.1\msvc2010\include\QtCore/qvector.h(532) : error C2248: 'QGraphicsRectItem::QGraphicsRectItem' : cannot access private member declared in class 'QGraphicsRectItem'
c:\qtsdk\desktop\qt\4.8.1\msvc2010\include\qtgui\qgraphicsitem.h(728) : see declration of 'QGraphicsRectItem::QGraphicsRectItem'
c:\qtsdk\desktop\qt\4.8.1\msvc2010\include\qtgui\qgraphicsitem.h(683) : see declaration of 'QGraphicsRectItem'
c:\QtSDK\Desktop\Qt\4.8.1\msvc2010\include\QtCore/qvector.h(473) : while compiling class template member function 'void QVector<T>::realloc(int,int)'
I know this may sound really stupid or really easy to do but I didn't find errors exactly like mine and I don't have a lot of experience with declarations. My question is how can I write this code in order to use my variable FreeLayer1. I insist on using QVector<>, I just don't know how to declare it.
Thank you for your help! :)

Your declaration is fine, the problem seems to be that QGraphicsRectItem's default constructor is private, so you can't use methods of QVector which need the default constructor, like QVector::resize. Looking at the docs for QGraphicsRectItem, there seems to be no public copy constructor or copy assignment operator either, so QGraphicsRectItem is not eligible as the element type of QVector. You'll have to store pointers to QGraphicsRectItem:
QVector<QGraphicsRectItem*> FreeLayer1;
FreeLayers1.resize(10);
FreeLayers1[0] = new QGraphicsRectItem(/* ... */);

Related

Drag and drop in QTreeWidget with custom class (Error :Qvariant::save)

my problem is the following :
I want to use a drag and drop in my QTreeWidget. My QtreeWidgetItem have the following flags Enabled | selectable |Drag | Drop.
It works for an item but don't for the rest (Error Qvariant::Save invalid type to save)
It's because we do some : setdata(QVariant::fromvalue<...
I understand since I want to use custom data, I need to make QVariant understand my class, and for this I need my class to have a default constructor, a copy constructor , a destructor, and 2 operator overlord << and >>.
friend QDataStream & operator << (QDataStream &arch, const MyClass & object)
After I need Q_DECLARE_METATYPE(MyClass) and register my operator with :
qRegisterMetaTypeStreamOperators<MyClass>("MyClass")
But I can't get it work. (still Error Qvariant::Save invalid type to save)
I need help to understand where everything goes.
My overloads operators are defined in my class (.H)
Should my Q_DECLARE_METATYPE be declared at the end of my class? (.h) will there be problem because somme class inherit from it? or because it have pure function?
I know many people use the qRegisterMetaTypeStreamOperators in the main but I can't do that, can I use it elsewhere (in the constructor of one my class or this will cause problem (like multiple declaration or multiple call like the connect functiun))
The error never change , is this normal or should Qt say to me "it recognizes the class I want to save but it doesn't everything needed"?
Ok i answered some of my question :
Q_DECLARE_METATYPE dosn't need to be in the .H (right now work with my .cpp)
You can use your qRegisterMetaTypeStreamOperators in the constructor (as a connect)
When QT reconise your class it will display another message (right now my problem is my class is an abstract class)
I'm trying to make it work with my current architecture
MyClass (Abstract)
- MyClassTemplate : MyClass
-MyClassA : MyClassTemplate<MyClassA>
-MyClassB : MyClassTemplate<MyClassB>
Ok i got it.
you can use an easy trick.
create a struct that has a pointer to the class you want to pass, and had operator << and >> in that class.
Q_Dclare_Metatype(your struct)
don't forget to qRegisterMetaTypeStreamOperators your struct
Since your class element is never destroyed you can just pass a pointer to it without any risk, and since you declared what type you will pass, qt accept it
(because when i was just apssing void * or other pointer type, qt reconisez that it had a specific type and would'nt work.
Hope it'll help you if you have the same problem

Error with sequence argument when using QtConcurrent map

I'm trying to use QtConcurrent::map to run this function
//This function is used through QtConcurrent::map to create images from a QString path
void MainWindow::createQImage(QString* path) {
//create an image from the given path
QImage* t = new QImage(*path);
imageList->append(t);
}
on this container/sequence (declared in the mainwindow header and initialized in the mainwindow constructor)
QList<QImage *> *imageList = new QList<QImage *>;
Here's the code I'm trying to run
QFutureWatcher<void> futureWatcher;
futureWatcher.setFuture(QtConcurrent::map(imageList, &MainWindow::createQImage));
and here are the errors I'm getting:
request for member 'begin' in 'sequence', which is of non-class type 'QList<QImage*>*'
request for member 'end' in 'sequence', which is of non-class type 'QList<QImage*>*'
I need the "createQImage" function to be run for every element in "imageList," which can reach into the thousands. I believe the problem to be with the first parameter to the map function. And from what I've read, it may have to do with compatibility. There isn't much sample code online that I was able to relate to. I'm new to Qt and not the most experienced of programmers but I'd appreciate some help and feedback.
Alternatively, is there better way to do this using QtConcurrent?
Thanks in advance!
QtConcurrent::map wants a sequence as its first argument. You passed it a pointer to a sequence.
If you do
futureWatcher.setFuture(QtConcurrent::map(*imageList, &MainWindow::createQImage));
it should be happy.
Note that the compiler was reasonably clear about what the problem was. Take the time to read the errors carefully, they're usually not as cryptic as they perhaps at first seem. In this case it was telling you that the argument you passed was not of a class type. A quick look at the argument type at the end of the error reveals that it is a pointer.
QList, QImage, QString are Copy-On-Write types (see other Qt implicitly shared types), so you shouldn't use pointers to these types because they are basically already smart pointers.
And if you remove all pointers from your code, it should also fix the main problem.

Storing pointers using QListWidgetItem::setData

I have a QListWidget of calendars. Each QListWidgetItem is logically associated with an instance of Calendar, which is a class that belongs to the Model side of the application.
Can I store this association in the form of a pointer using QListWidgetItem::setData? When I attempt to do this, I get the following error:
error: 'QVariant::QVariant(void*)' is private
There is another constructor for void*: QVariant::QVariant(int typeOrUserType, const void * copy) where you should pass an unique integer to represent the pointer type.
But as stated by the documentation, you could declare your pointer type with Q_DECLARE_METATYPE(Calendar*) and use QVariant::fromValue<Calendar*>(...) and QVariant::value<Calendar*>() to store and retrieve the value.
Or instead, because you are using a QListWidget instead of a regular model, you can just subclass QListWidgetItem, and add a Calendar* member variable with the required accessors, to avoid the overhead of using QVariant.
I would suggest looking at this solution as well, which I think is quite elegant:
(there are minor syntax errors, but you will spot them quickly or the compiler will issue an error)
https://web.archive.org/web/20171025163314/http://blog.bigpixel.ro/2010/04/storing-pointer-in-qvariant/

qt tr() in static variable

I have problem concerning translations in qt. All translations in my porject work fine, but one, which is in a static variable of a class. Corresponding part of code looks as follows
The header file is similar to this:
typedef struct {
int type;
QString problematicString;
} info;
MyClass::QObject_Descendant
{
Q_OBJECT;
//some functions like constructor, destructor... etc.
....
static info myClassInfo;//class that makes problems
}
and in implementation file I initialize the variable as follows:
info MyClass::myClassInfo={
1,
tr("something to be translated")
};
And whatever I do (trying with QT_TR_NOOP, then tr() and others) I cannot get myClassInfo.problematicString translated. The weirdest thing is that the text "something to be translated"
appears in *.ts file.
If someone has any hints, please share them with me. Thanks in advance.
Chris.
Static variables are instantiated (and thus, constructor code run) before your int main function is run. The translation code is set up in the QApplication constructor (I believe), which isn't run until your int main function has been entered. Thus, you are trying to get the translation of a string before the code to support it has been initialized.
To avoid this, you could either accept that the given string isn't translated and explicitly translate it every time it is used, or use the Construct on First Use idiom instead of a static member variable.

Qt signals & inheritance question

I am relatively new to programming with Qt and had a question. Short version:
How do I inherit signals defined in superclasses?
I am trying to subclass someone else's nicely made QTWidgets to change some of the default behavior:
//Plot3D is a QWidget that defines a signal "rotationChanged"
class matLinePlot : public QObject, public Plot3D {
Q_OBJECT;
//etc...
public:
//etc...
//Catch Plot3D's signal "rotationChanged" and do some magic with it:
void initPlot(){
QObject::connect(this, SIGNAL(rotationChanged( double , double , double )),
this, SLOT(myRotationChanged(double, double, double)));
}
};
The problem is in the QObject::connect line. What I would like to do is connect the rotationChanged SIGNAL (from qwt3D_plot.h) to a local function/SLOT - "myRotationChanged". However whenever I do this, at run time I get:
Object::connect: No such signal matLinePlot::rotationChanged(double, double, double)
in C:...\matrixVisualization.h. Of course, I know that rotationChanged isn't in matrixVisualization.h - it's in qwt_plot3D.h, but I thought that since I inherit from Plot3D everything should be fine. But, now that I think about it, since SIGNAL and SLOT are macros, I assume MOC doesn't know/care about inheritance.
Which leads me to my question - since MOC and SIGNALS / SLOTS don't seem to know about inheritance etc: how can I subclass a widget defined somewhere else and get access to the widget's signals?
I have a lot of examples of how to use encapsulation to accomplish something like this, but I'm afraid I don't understand how to do this with inheritance.
Sorry if this is a ridiculous question - I feel like I'm missing something obvious.
I guess the problem is the multiple inheritance:
class matLinePlot : public QObject, public Plot3D
...
I assume that Plot3D is a subclass of QObject? In this case, you should do
class matLinePlot : public Plot3D
...
instead.
SIGNAL(x) and SLOT(x) are macros that generate string literals. At runtime, slots and signals are matched up using string compares of those generated literals.
(I would have added a comment to mdec's comment, but I don't have enough rep)
I believe that will work if the Plot3D::rotationChanged signal is public or protected. Are you sure the signal is not private?
Edit:
Although I could not find a specific reference, I'll have to conclude that signals are always public. At least a test I did here seemed to indicate that I could connect to a signal even if it was declared in the private section of a class.
I also verified that a signal declared in QObject could be connected using a subclass of QObject in the connect statement so signals are definitely inheritable. As I see in other answers and comments here, the issue must be elsewhere.
Incorrect -> see comments.
I'm using Qtopia at Uni and I believe I recall someone saying something about spacing in the SIGNAL and SLOT parameters for connect.
Try using
QObject::connect(this, SIGNAL(rotationChanged(double,double,double)),
this, SLOT(myRotationChanged(double,double,double)));
I know it doesn't seem intuitive, as C++ isn't sensitive to whitespace, however I believe it has something to do with some of the magic that Qtopia/QT uses when connecting signals and slots. This may only apply to Qtopia, or I may have heard wrong, but give it a try. Additionally are the signals public or protected and have you included the appropriate header files?

Resources