How to set user data for a QWidget? - c++

I would like to set an integer number to be stored in a QWidget, and I think the setUserData member function would do the trick but I can't find any documentation. Any hints?

You might be looking for QObject::setProperty() (which is of course inherited by QWidget).

I am not an expert in QT but why not just create a class that inherits from QWidget and has an integer? Like so:
class MyDerivedWidget : public QWidget
{
public:
MyDerivedWidget();
private:
Data *myUserData;
};
Or if you insist on using the setUserData checkout the last post here.

Related

Use Q_PROPERTY's from a costum class in QML

I'm stuck with a "design/implemantation" problem in Qt.
At the moment I'm not even sure if thats a smart design...
That's my first post here and I don't really know where to start...
So I'll try is this way...
At the moment I have something like this:
class NewProperty : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
.
.
.
public:
NewProperty(const QString &name, QObject *parent = 0);
QString name()const;
void setName(const QString &name);
.
.
.
private:
QString m_s_name;
};
That's a "NewProperty" Class I want to have in "MyClass" cause in the end there will be much more than just a "name" Property ... The NewProject.cpp file is pretty basic at the moment...
And there will be also several MyClasses in the project.
My "MyClass" will have several "NewProperty" 's elements in the end...
But I'm not sure how to pass the "NewProperty" to QML in the/a right/nice way.
I tried to do something like this:
class QML_EMail : public Base_Output
{
Q_OBJECT
public:
NewProperty prop1;
NewProperty prop2;
.
.
.
};
main.cpp
...
qmlRegisterType<NewProperty> ("NewProperty", 1, 0, "NewProperty");
QML_EMail email
ctx->setContextProperty("email", QVariant::fromValue(&email));
...
If I try to call something like this in the QML file:
import NewProperty 1.0
Rectangle {
id: emailStart
Component.onCompleted:
{
console.log(email.prop1.name)
}
I only get this Message: TypeError: Cannot read property 'name' of undefined
I would appreciate any help or hints for better coding...
regards,
Moe
Welcome to Stack Overflow.
I don't think Qt properties can be used like that. If you want to access properties from QML the class (QObject based) members have to be defined with Q_PROPERTY itself to be exposed by Qt's meta object system. So you can't simply use another class that also has properties in it like that.
Essentially you have nested objects with properties, so you also have to flag them as such, if you want to use them in QML. An easy solution is to use the MEMBER keyword if you don't need getters and setters:
Q_PROPERTY(NewProperty prop1 MEMBER prop1)
NewProperty prop1;
You still might have to expose your custom NewProperty class to the meta system if you want to use it like that as a property. See Creating Custom Qt Types for more info about custom types.

I would like to use the span slider from Qxt without having to install it. Is this possible?

I stumbled across a widget that provides you with a slider with two handles so you can select a range between an upper and lower limit.
I would like to use it without having to install all of Qxt though, since I am pretty sure this is the only thing that I need.
How can I deal with qxt_p() in order to use this widget as a standalone?
You need to add the following in the main class:
private:
QxtSpanSliderPrivate* d_ptr;
friend class QxtSpanSliderPrivate;
And in the following in the private class:
private:
QxtSpanSlider* q_ptr;
friend class QxtSpanSlider;
Also you should remove Qwt macros usage and replace qxt_d() and qxt_q() with direct access to q_ptr and d_ptr.
Each constructor of the main class should initialize both pointers:
QxtSpanSlider::QxtSpanSlider(Qt::Orientation orientation, QWidget* parent) :
QSlider(orientation, parent),
d_ptr(new QxtSpanSliderPrivate())
{
d_ptr->q_ptr = this;
//...
}
In case I forgot something, here is the gist. This code allowed me to successfully use QxtSpanSlider in Qt5.

Qt Extending my own widget

To put it simply, I want a new class that extends a custom widget that I've made, and thus have full access to it's UI.
I've tried several different methods so far based on how one would normally subclass/extend classes, but I'm somehow failing horribly for so many different reasons.
Additionally, simply using my widget as a member in my new class wouldn't do for this situation.
Can someone illustrate a quick example of how I would do this? I have done a bunch of searching but I can't seem to find any hits relating to exactly what I'm trying to do
If all else fails I will simply copy over the code and make an actual new widget, which technically would have saved me lots time, but it just doesn't feel right doing that.
My first instinct was to do something like this ( Qwe being my new class, Asd being the widget ):
class Qwe : Asd {public: ...}
And I even made the widget's Ui public, but then I just got the error :
use of undefine type Ui::Asd
whenever I tried to access the Ui's elements.
Let's say we have a custom widget named BaseWidget and a child widget named ChildWidget. Declare BaseWidget as usually, but make its ui member protected instead of private, like this:
protected:
Ui::BaseWidget *ui;
Declare ChildWidget as an ordinary widget derived from BaseWidget. Make sure you include ui_BaseWidget.h in the ChildWidget.cpp file, just as you do it in BaseWidget.cpp (this include and the header itself is generated by Qt).
Header:
#include "BaseWidget.h"
class ChildWidget : public BaseWidget {
Q_OBJECT
public:
explicit ChildWidget(QString text, QWidget *parent = 0);
};
Source:
#include "ChildWidget.h"
#include "ui_BaseWidget.h"
ChildWidget::ChildWidget(QString text, QWidget *parent) :
BaseWidget(parent)
{
ui->label->setText(text);
}

Qt4: The best way to access parent class (1 level up, 2 levels up .... )

I'm wondering how to access parent class in my Qt application.
Lets say my project has following structure:
mainWindow: MainWindow
tabWidget: QTabWidget
tab1: MySubClass1
tab2: MySubClass2
tabWidget: QTabWidget
xtab1: MySubSubClass1
xtab2: MySubSubClass2
It is a little simplified.
What I want to do is to access mainWindows object from one of xtab2 slot functions.
(1) What would be the best method ?
I tried to pass the pointer to mainWindow along the tree but I get runtime errors.
(2) Should I include mainwindow.h in xtab.h file or should I do it in xtab.cpp file ?
Thanks for help :)
If you really need the mainwindow, passing the MainWindow pointer is the best way to do it. A static method has the drawback that it will stop working with more than one mainwindow.
I would suggest to avoid accessing the mainwindow from the contained widgets though and use signals instead. E.g.:
class MainWindow {
public:
explicit MainWindow( QWidget* parent=0 ) {
tab = new TabWidget;
...
MySubSubClass1* ssw1 = new MySubSubClass;
connect( ssw1, SIGNAL(textChanged(QString)), this, SLOT(page1TextChanged(QString));
tab->addWidget( ssw1 );
}
private Q_SLOTS:
void page1TextChanged( const QString& ) {
//do something...
}
};
MySubSubClass1 then emits textChanged(), addresseeChanged() (e.g. in Addressbook), or whatever level of abstraction or detail makes sense on the higher level. That way MySubSubClass is generic and doesn't have to know about MainWindow at all. It can be reused in any other context. If MySubSubClass itself contains other widgets, it can again connect to their signals.
You could create a static method and object inside MainWindow that would return mainwindow object.
Something like this:
private:
static MainWindow* _windowInstance
public:
static MainWindow* windowInstance()
{
return _windowInstance;
}
This seems to be the simples solution in most cases. Now you just have to include mainwindow.h whenever you need to access this object.
And don't forget to initialize _windowInstance in the contructor, like this;
_windowInstance = this;
By parent class, I assume you mean parent widget?
If you want to find the top level widget, QWidget::window() will point you to it. Use dynamic_cast or qobject_cast to turn it into your MainWindow object.
If you want to go up some arbitrary level, use paerntWidget().
There are a variety of different solutions to this problem, the one you chose as the answer is in terms of object orientation and encapsulation one of the worse ones. Some thoughts
Encapsulation: if you find yourself having to provide access accross a large distance in relation (down a long chain of containers or subclasses) you might want to look at the functionality that you are trying to distribute. I might be that it should be encapsulated in a class by itself that can passed around easier than where it is currently located (the main window in your case).
Abstraction: Unless it is actually functionality of QMainWindow that you need to access don't pass a pointer to your MainWindow class, create an interface for the functionality that you need, have your MainWindow implement that interface and pass around and object of the interface type instead of your MainWindow type.
Signals and Slots: As Frank noted, implement the appropriate functionality using Qt's signalling mechanism, this makes the connection between the caller and callee into a dynamic one, again separating it from the actual MainWindow class
QApplication: If you absolutely have to have global information restrict the entry point, you already have one singleton the QApplication object, make it the maintainer of all the other objects that need to be globally accessible, derive your own QApplication class and maintain global references in there. Your QApplication class can then create or destroy the needed global objects.
With more information about what you need to do with the MainWindow instance or what needs to be communicated you will also get better answers
QWidget* parent = this ;
while (parent -> parentWidget()) parent = parent -> parentWidget() ;

Subclassing QGraphicsItemGroup

I have system that has classes derived from QGraphicsWidget. I manage derived class objects in layouts on QGraphicsScene. Now I need a compound item that contain two or more QGraphicsWidget in it and also I need to put that item inside my layout. So I choose QGraphicsItemGroup and write I class like this.
class CompositeItem : public QGraphicsItemGroup,public QGraphicsLayoutItem
{
...
};
I only implemented sizeHint function again.
When add CompositeItem instance to layout it does not shown.
What may cause this? Where I made wrong?
Call show() on either the QGraphicsItemGroup or QGraphicsWidgets after adding to the layout.
Add setGraphicsItem( this ) to your constructor.