Reputation: 972
I am trying to change the border of a QFrame. BUT.
There is a Window::ui, inside of which there is a class inheriting from QWidget. In that class, there is a QFrame, set with a vertical Layout, which holds 2 other QFrame and do their QFrame business. Now, this structure is repeated a lot in Window::ui, so I simply added it to a vertical layout named kingdom_decks.
So far, so good.
Let's say, I want to select one of those element. To mark the selection, I want to change the border, from black to red, or just make it thicker. With a QFrame, very easy. BUT
My event handler is a slot in Window::ui. ui
goes to kingdom_decks layout, and go to the item selected. itemAt retourn a QLayoutItem, that I can cast as QWidget with widget()... but then?
ui->kingdom_decks->itemAt(idx_prev)->widget()
I tried unsuccessfully
ui->kingdom_decks->itemAt(idx_prev)->widget()->childAt(0,0)
I believe it failed because there is a Qframe in a Layout, instead of a geometry form with real coordonates, or maybe I didn't go deep enough?
Anyway, thank you very much in advance for any ideas on that! Thanks for your time.
EDIT
Code for window.cpp
#include "window.h"
#include "ui_window.h"
Window::Window(Game_state * p, Card_generator * d, QWidget *parent) :
QDialog(parent),
ui(new Ui::Window)
{
ui->setupUi(this);
/*Stuff happen here*/
/* Display cards*/
for (int i = 0; i < 10; ++i){
/*Add widget to layout*/
ui->kingdom_decks->addWidget(new Cards_kingdom(decks->decks_kingdom[i]),0,i);
/*Connect widget to map*/
connect(ui->kingdom_decks->itemAt(i)->widget(), SIGNAL(mousePressEvent()), signal_mapper, SLOT(map()));
/*Map widget and data*/
signal_mapper->setMapping(ui->kingdom_decks->itemAt(i)->widget(), i);
}
/* Action "Select cards" */
connect(signal_mapper, SIGNAL(mapped(int)), this, SLOT(card_kingdom_selected(int)));
}
Window::~Window()
{
delete ui;
}
/*Implementation of SLOT*/
void Window::card_kingdom_selected(int idx){
/*...*/
//?????????????? What to do here???????????
//ui->findChild<QLabel *>("img");
//ui->kingdom_decks->itemAt(idx)->widget()->????;
}
So what happen here is that I have a layout kingdom_decks, in which I loop to add a widget Cards_kingdom, overloading the function addWidget.
ui->kingdom_decks->addWidget(new Cards_kingdom(decks->decks_kingdom[i]),0,i);
This Object Cards_kingdom is a class, such that:
cards_kingdom.h :
class Cards_kingdom : public QWidget {
public:
Cards_kingdom(Deck_kingdom * input_deck); /* Constructor */
bool isSelected();
QLabel * get_img();
/*
* Price and Counter are display in the same label, then are wrapped with Icon in a vertical layout, inside a frame.
*/
private:
QLabel *img; /* Icon */
QLabel *info; /* Nb Cards left*/
QVBoxLayout *layout; /* Layout */
QFrame *pack; /* Frame */
Deck_kingdom *deck; /* Type Deck */
bool select;
};
In window.cpp, i try to retrieve the QLabel * img
, to put a border on this image, such that the user sees that it has been selected.
To answer to @Nicholas Smith, how can findChild, find the exact instanciation of Card_kingdom
?
EDIT:
OK, I could change my architecture to something like this:
Create a vector of Cards_kingdom * vec
In the for loop, vec.push_back(new Card_kingdom *); ui->layout->addWIdget(vec[i])
So now, I think that would work, because layout is holding a pointer to my widget, so I pass by reference, therefore, if I change something in my object, it will appear in the GUI even if I didn't pass by there...
Right? :)
Upvotes: 0
Views: 605
Reputation: 11754
The fun thing with Qt is layouts can become nests and layers and mazes, but I've just had this exact issue with a different twist, I'd personally go for something along the lines of ui->findChild<QFrame *>("frameObjectName")
(if you've created QFrame as pointer, if not just drop the *) and access it from there. You'll need to make sure you have an object name filled it for the frame, but that's not too hard and has other benefits.
Upvotes: 0