PDA

View Full Version : How to set the base widget when subclassing Qt widget



Cupidvogel
28th February 2015, 02:31
So I need a custom widget which will subclass QFrame. I do the subclassing, and everything works fine. Except that, there is no way way to set this inside a method. As a result, when I call normal methods that are applicable to QFrame on my custom widget, such as setGeometry, it does nothing. Because I have nowhere specified that. How do I specify that? My code:



class MyWidget: public QFrame
{
MyWidget(QWidget *parent);

private:
prapareUI();
QWidget *parent;
QFrame *baseWidget;
}

MyWidget::MyWidget(QWidget *parent): parent(parent) {
prepareUI();
}

MyWidget::prepareUI() {
baseWidget = new QFrame(parent);
//do other stuff, add more widgets to base class, it is the container after all
}

//main class
MyWidget *widget = new MyWidget(this);
widget->setGeometry(50,50,100,100);


The widget appears fine as expected, all UI elements added properly inside it. However, because I could not tell main that the setGeometry method on MyWidget should actually call setGeometry internally on the QFrame member variable baseWidget, it does nothing, and it is positioned on the top left corner of the widget by default. How do I fix this? I can extend setGeometry of course, so that it will internally call setGeometry on the baseWidget, but then, this way I will have to redefine many built in methods. Is there no way I can tell the widget that 'this' refers to 'baseWidget'?

ChrisW67
28th February 2015, 06:08
BaseWidget is positioned in the top left because you gave it the MyWidget instance as a parent and, I am guessing, did not put it in a layout applied to the MyWidget instance. What is the function of baseWidget? Have you put other widgets inside it instead of inside the MyWidget container? It certainly sounds like that from your questions.

Lesiok
28th February 2015, 08:41
As I see class MyWidget is inherited from QFrame. So for what is QFrame *baseWidget ?

Cupidvogel
28th February 2015, 09:26
As I see class MyWidget is inherited from QFrame. So for what is QFrame *baseWidget ?

Yes, that is the problem you see. I want this to be baseWidget. So that the parent of this (or baseWidget) is the parent widget I pass in as parameter. How do I do it?


BaseWidget is positioned in the top left because you gave it the MyWidget instance as a parent and, I am guessing, did not put it in a layout applied to the MyWidget instance. What is the function of baseWidget? Have you put other widgets inside it instead of inside the MyWidget container? It certainly sounds like that from your questions.

Yes, baseWidget will have lots of sub-widgets in it. I pass in the parent because it has to be positioned at a particular position in the parent widget, layout agnostic. If I do


QFrame *baseWidget = new QFrame(this);
baseWidget->setGeometry(x,y,width,height);
//add more widgets to baseWidget

in the parent widget code, it works fine. I want to do the same things, except baseWidget will be of type MyWidget that inherits from QFrame.

Lesiok
28th February 2015, 10:08
Are you sure you know what is the classe inheritance ?
Class MyWidget is QFrame too. You do not need field baseWidget and extra WFrame object.

Cupidvogel
28th February 2015, 10:12
Yes, I know that. I tried this as well:



this->setStyleSheet("background: rgb(246,247,239); border-radius: 5px;");
this->setParent(parent);
this->show();


instead of creating a new QFrame baseWidget. Doesn't work. Doesn't show up at all, unlike the last one where it showed up but not taking the geometry correctly.

ChrisW67
28th February 2015, 10:26
Construct MYWidget so that the content you put in baseWidget is its content, and throw away baseWidget, then you will get what you are expecting.

Cupidvogel
28th February 2015, 10:46
Yes, I am doing that only. Previously I was doing this:


MyWidget::MyWidget(QWidget *parent): parent(parent)
{
prepareUI();
}

MyWidget::prepareUI()
{
QFrame *baseWidget = new QFrame(parent);
baseWidget->setStylesheet("...");
QLabel *label = new QLabel(baseWidget);
label->setText("...");
}

//in main:

MyWidget *widget = new MyWidget(this);

Now I am doing this:


MyWidget::MyWidget(QWidget *parent): parent(parent)
{
prepareUI();
}

MyWidget::prepareUI()
{
this->setStylesheet("...");
QLabel *label = new QLabel(this);
label->setText("...");
this->show();
}

//in main:

MyWidget *widget = new MyWidget(this);
widget->show();

Still it doesn't show anything at all.

Added after 7 minutes:

No no, it's working now. I did not do a clean build, so it was taking the old code.. :D

ChrisW67
28th February 2015, 19:57
Nearly there. Now read about Layout Management (http://doc.qt.io/qt-5/layout.html) to get the knowledge needed to have nicely resizable widget.

Cupidvogel
28th February 2015, 19:58
Thanks. Will do. :)