View Full Version : How to work with the replaceWidget function from QGridLayout
KeineAhnung
29th April 2014, 12:08
Hi there,
I created a QGridLayout and willed it with several GroupBoxes. To update the boxes I planned to replace them since I could not find a possibility to change a label within the GroupBox that is part of the QGridLayout.
In the documentation I found this: QLayoutItem * QLayout::replaceWidget(QWidget * from, QWidget * to, Qt::FindChildOptions options = Qt::FindChildrenRecursively) but I do not understand it. *to is clear, this is my newly created widget but how do I get the *from widget? I know the position in the grid but there is no function that gives me a widget, they only give me items, which is not working.
Can anybody post some example code that shows how this function is used?
Thanks a lot!
anda_skoa
29th April 2014, 13:09
Can you elaborate why changing a label inside a groupbox would not work just because the groupbox is in a gridlayout?
Cheers,
_
KeineAhnung
29th April 2014, 13:47
Because they are created during a PushButton event:
propLabel[stationIndex] = new QLabel(updateStation(stationIndex));
And propLabel[sationIndex]->setText(updateStation(index)); in a different PushButton event does not work:
.../mainwindow.cpp:150: Fehler: no member named 'propLabel' in 'Ui::MainWindow'
ui->propLabel[activeIndex]->setText(updateStation(activeIndex));
~~ ^
anda_skoa
29th April 2014, 17:00
You are trying to address a list, vector or array inside the instance pointed to by "ui", which does not have a variable of the name "propLabel"
The code for creating the label works then you have that variable in some other instance.
Cheers,
_
KeineAhnung
29th April 2014, 17:36
Hi,
thanks _ for the support so far. I am completely lost here.
As I said the label is within a group box that is added to the grid layout here:
ui->cardLayout->addWidget(stationCard[stationIndex], stationIndex/4, stationIndex%4);
While the program runs these cards need to be updated but so far I was not able to find a way to do that. The only thing that worked was adding a new card to the same coordinates but I guess that stacks them rather than updating them. I was not able to figure out how this replaceWidget function works or how I can access on of the cards.
anda_skoa
29th April 2014, 18:41
Well, you seem to have all your station widgets (groupboxes) in a container named stationCard, probably an array, a vector or a list.
So given you have a stationIndex for which you want to update a label, you should always be able to get the station card for that index from that container.
If the class of the station card widget in there has a setter that internally accesses the label, then you should also be able to change the label's text.
Lets assume your station card widget it something like this
class StationCard : public QGroupBox
{
public:
void setStationName(const QString &name)
{
m_nameLabel->setText(name);
}
private:
QLabel *m_nameLabel;
};
stationCard[stationIndex]->setStationName(someStationNameString);
Cheers,
_
KeineAhnung
30th April 2014, 00:34
Hi _,
thanks for the hint. Actually I do not have a container. The stationCard is the widget and is passed directly to the layout, it is not stored in a container first. I guess the layout does not work as container...
As you suggested I will create a new class first and add this class to a vector and than have the vector displayed in the layout. Actually this was one of my questions I posted in another thread, how to combine different UI elements in a class.
anda_skoa
30th April 2014, 08:42
thanks for the hint. Actually I do not have a container. The stationCard is the widget and is passed directly to the layout, it is not stored in a container first. I guess the layout does not work as container...
The layout is a kind of container, just not as easily addressable by index.
But your code had stationCard (and previously propLabel) as a container, it is accessed by index in your code snippets.
Cheers,
_
KeineAhnung
30th April 2014, 09:36
So I tired to redo my code but either I get QLayout: Cannot add null widget to QGridLayout/cardLayout or the program crashes.
From the beginning. I created a new class StationCard. This class is based on the QGroupBox and adds a QLabel to it, right?
.h
#ifndef STATIONCARD_H
#define STATIONCARD_H
#include <QLabel>
#include <QGroupBox>
#include <QLayout>
class StationCard : public QGroupBox{
public:
StationCard();
QLabel *propLabel;
private:
};
#endif // STATIONCARD_H
.cpp
#include "stationcard.h"
StationCard::StationCard(){
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(propLabel, 10, Qt::AlignRight);
setLayout(layout);
}
In my main window .h I added the .h file of the new class and crated a vector:
QVector<StationCard*> stationVector;
In my main window .cpp I first want to fill my grid with empty cards:
stationVector.resize(8);
int k = 0;
for(int i = 0; i < 2; ++i){
ui->cardLayout->setRowMinimumHeight(i,200);
for(int j = 0; j < 4; ++j){
ui->cardLayout->setColumnMinimumWidth(j, 150);
ui->cardLayout->addWidget(stationVector[k], i, j);
k++;
}
}
But this already gives me QLayout: Cannot add null widget to QGridLayout/cardLayout and if I want to fill it, the program crashes. If I say stationVector.resize(8), does this not create an array with eight elements of my custom group box class? If I try to do stationVector[k] = new StationCard, it crashes right away. =(
Added after 5 minutes:
But your code had stationCard (and previously propLabel) as a container, it is accessed by index in your code snippets.
_
Actually no. I followed a tutorial here where they created several buttons using a for-loop. http://doc.qt.digia.com/4.4/layouts-basiclayouts.html
stampede
30th April 2014, 10:10
QLayout: Cannot add null widget to QGridLayout/cardLayout or the program crashes.
Because you have to create the label instance
StationCard::StationCard(){
QHBoxLayout *layout = new QHBoxLayout;
propLabel = new QLabel(/*parameters*/);
layout->addWidget(propLabel, 10, Qt::AlignRight);
setLayout(layout);
}
anda_skoa
30th April 2014, 10:15
As you found out yourself already, you need of course create instances of StationCard before you can add them.
stationVector[k] = new StationCard
You experience a crash because your StationCard constructor tries to add an uninitialized pointer (propLabel) to a layout.
Create a QLabel instance first :)
Cheers,
_
P.S.: you can do the StationCard in designer if you want to, just use the widget template for a designer form and add the "ui" pointer and related code lines manually to your class
KeineAhnung
30th April 2014, 10:44
Thanks for the help! Now the program is running and I can tackle the next step to connect the checkbox from the group box. As you can see I am missing a lot of the basic stuff but I am just not good at reading books. I always try to start in the middle...
anda_skoa
30th April 2014, 12:33
You can "forward" signals
class StationCard : public QGroupBox
{
signals:
void somethingToggled(bool on);
};
StationCard::StationCard()
{
connect(someCheckBox, SIGNAL(toggled(bool)), this, SIGNAL(somethingToggled(bool)));
}
Cheers,
_
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.