Qt - how to make QPushButton change between two QVBoxLayouts - c++

So i have a main layout called the 'vboxmain'. And the program has two states: blackjack and poker. For both I have a button. In this vboxmain I have an upper part, which covers most of the program, and is the same for both games, but I also have a bottom part which should display different parts for both games. For example, poker game should hold five QCheckBoxes and one button. As for the blackjack game i need simply two buttons. I created both of these bottom layouts as QVBoxLayouts. So now i have:
BlackjackiValikud = new QVBoxLayout; //for blackjack
Pokkerivalikud = new QVBoxLayout; //for poker
And I tried creating two button actions like this:
void mainwindow::BlackJack_clicked(){
vboxmain->removeItem(Pokkerivalikud);
vboxmain->addItem(BlackjackiValikud);
}
void mainwindow::Poker_clicked(){
vboxmain->removeItem(BlackjackiValikud);
vboxmain->addItem(Pokkerivalikud);
}
Buttons are connected like this:
connect(BlackjackButton, SIGNAL(clicked()), this, SLOT(BlackJack_clicked()));
connect(PokerButton, SIGNAL(clicked()), this, SLOT(Poker_clicked()));
But currently it's not working and I can't figure out a way to do this, so I'm asking for help. This is probably not the best way to do this either but I don't know any other ways. So I could use some help on how to make this work with whatever solution - so that with both buttons I can change the bottom part of my vboxmain as needed.
I'm open to solutions.

What do you mean by it is not working?
You have to make sure that the layout are enabled when you add them (via QLayout::setEnabled ( bool enable)) or that widget are visible (via QWidget::show()). In general you have to manuable make visible items which are added to a widget which is already visible...
An alternative would be to use a QStackedLayout to display either. You have a widget poker for the poker view and a widget blackjack for the black jack view. On button push you use either
void QStackedLayout::setCurrentIndex ( int index )
void QStackedLayout::setCurrentWidget ( QWidget * widget )

You may want to keep the layouts and change what's presented in the bottom layout. To do so, create classes for each game(say blakjackWidget and pokerWidget) derived from QWidget. and show only one of them in the bottom layout.

Related

wxWidgets - Hide/Show contents of of a `boxsizer` on button click

I'm very new to C++, only 2 weeks, before this, I was learning python and used Tkinter to make a music player, as a practice project, until recently I discovered wxWidgets and used wxPython then I switched to C++, as I really wanted to learn C++. I have this playlist listbox widget, which I have in the same frame inside a panel widget, and its own boxsizer widget, I want it so that it hides and shows, on a button click, and main window resizes accordingly automatically. I searched around for how to do that, I did find Show() and Hide(), and I was able to achieve the effect I want, but the main window does not resize correctly, it stretches weirdly and shows the playlist in wrong size.
The function for button that hides the playlist looks like this
void Frame::Playlist(wxCommandEvent &event)
{
if (playlistButton->GetValue() == 1)
{
hboxSizer8->Show(true);
hboxSizer9->Show(true);
hboxSizer8->Layout();
hboxSizer9->Layout();
vboxSizer->Layout();
panel->SetSizerAndFit(vboxSizer, true);
}
else
{
hboxSizer8->Show(false);
hboxSizer9->Show(false);
hboxSizer8->Layout();
hboxSizer9->Layout();
vboxSizer->Layout();
panel->SetSizerAndFit(vboxSizer, true);
}
}
and the button is set up like this
playlistButton = new wxToggleButton(panel, wxID_ANY, wxT("Playlist"), wxDefaultPosition, wxDefaultSize, 0);
playlistButton->Bind(wxEVT_TOGGLEBUTTON, &Frame::Playlist, this);
I'm adding a GIF to explain the problem better.
Also is there a widget or some feature in wxWidgets that can make a separate window, so I can like make a separate window that holds my playlist instead of same window for everything, and they can like snap together and join, when user brings them close to each other.
You need to call Layout() on the topmost sizer after you Hide()/Show().
Also, take a look at the auidemo and check the documentation about wxAUI* classes.
Sizers are not windows. You should call Hide()/Show() on the wxListBox only and then call Layout() on the topmost sizer.

How can I create a QPushButton with a custom (triangular) shape in Qt 5.5?

How can I create a triangular pushbutton in Qt? What is the most simplest way of executing this? I use the designer to create buttons and not code.
Also, I read somewhere that shapes may be changed as long as the frame of the button is still rectangular but I want the frame to adjust according to the shape as well. How can I achieve this?
More detail: I want to place lots of small triangular buttons next to each other with every other triangle flipped. Each triangle button has it's own function, etc (no overlapping borders accepted). Can anyone give me a descriptive explanation for how I might go about this?
The geometry on a QWidget is always a rectangle.
It would be possible to create a QPushButton derivative, override its paintevent and do some nasty painting considering its neighborhood etc. but it would be really a pain...
it is much easier to use a QGraphicsView, QGraphicsScene and add appropriate QGraphicsItem (maybe the QGraphicsPolygonItem?), add them and use their signals/slots or create a derived class for your purposes.
It is not that hard to override the mouseevents to recognize clicks and you can even use the QStyleSheets to let the "button" look like it gets pressed.

Placing QWidgets at specified coordinates?

Context: I'm making Risk (the popular board game) in C++/Qt, and I've run into a problem. I decided to make the map interactive by placing buttons on every country, which could then be clicked on. After some experimenting, I've subclassed QGraphicsPixmapItem for the buttons, and stuck them inside a QGraphicsScene and a QGraphicsView. I've made the world map a background image via CSS, so that buttons could be overlaid without much hassle.
My problem: I want to place those buttons at specific coordinates. (If it matters, those coordinates would be absolute.) All of the interfaces that I've made so far, I've done in code - I'm not familiar with the Qt Designer, so I'm looking for a function or set of functions that'd let me place my buttons (more or less) where I want them.
What I've tried: I looked in the documentation, but couldn't find a function that let me control where items were placed, just ones that organized items in various ways - columns, horizontal boxes, vertical boxes, etc.
When I designed QWidgets before, I'd done so by placing buttons, other widgets, etc. in QLayouts, but there don't seem to be layouts that allow me the control I'd like. The only one I can see that'd do something similar, is QGridLayout, and experiments with that so far haven't worked the way I wanted them to - the buttons don't get anywhere near the edges of the map, no matter how many columns or rows I add.
The easiest solution would be giving up and placing the buttons beside the map, of course, but that's a last-ditch solution.
Thanks in advance.
EDIT: Added example source code, for clarity.
QHBoxLayout* layout = new QHBoxLayout;
TerritoryButton* test = new TerritoryButton(QPixmap("img.png"));
TerritoryButton* test2 = new TerritoryButton(QPixmap("img.png"));
QGraphicsScene* scene = new QGraphicsScene;
QGraphicsScene* scene2 = new QGraphicsScene;
scene->addItem(test);
scene2->addItem(test2);
QGraphicsView* view = new QGraphicsView(scene);
QGraphicsView* view2 = new QGraphicsView(scene2);
layout->addWidget(view);
layout->addWidget(view2);
setLayout(layout);
setFixedSize(1000, 512);
QGraphicsPixmapItem inherits QGraphicsItem, so you can call setPos(x, y) (after inserting the pixmap item into the scene with addItem).
void QGraphicsItem::setPos(const QPointF &pos)
Sets the position of the item to pos, which is in parent coordinates. For
items with no parent, pos is in scene coordinates.
The position of the item describes its origin (local coordinate (0, 0)) in parent coordinates.

How to add a widget to a pre-existing QLayout?

I'm looking for a super simple example, and can't seem to find one. I have a MainWindow. When a button gets pressed I want to create a new window that gets opened up in the layout of MainWindow, to become a part of the mainwindow.
I have the code that sets up when a button is pushed to call this slot...when it gets called my QLabel shows up, but my QWidget does not
QWidget *test = new QWidget();
test->setGeometry(QRect(100,100,100,100));
layout->addWidget(test,0,0)
//Operation Mode
QLabel *operationalModeLabel1 = new QLabel("TEST");
layout->addWidget(operationalModeLabel1,2,1);
The reason for "lack of examples" is that you think of it wrong. What you describe is done all the time, by every single Qt example that uses layouts! I mean it. It doesn't matter when you add a widget to a layout. There's nothing magical about adding widgets "now" vs. adding them "later".
Just think of the title of the question: it makes no sense. All widgets must be added to layouts that already exist! By definition, no less. If there's no layout, how could you add a widget to it?
Your code is wrong, that's all. It's always pointless to set a geometry on a widget that is to be managed by a layout. As soon as you add it to the layout, the layout will change the geometry.
Since you're adding an empty widget into the layout, you most likely won't be able to see it. That's why the label shows up - it's not an empty widget.
If you want a widget that has a fixed size, to make it easier to notice, just set the fixed size on it. Even better, make it red so that it stands out.
QWidget * test = new QWidget();
test->setStyleSheet("QWidget { background-color: red }");
test->setFixedSize(100, 100);
layout->addWidget(test, 0, 0);

qt - widget - positioning

I want to place some widgets in a parent widget in some random places, like one button at Point (10,10) and another at (15,40), etc. How to achieve this?. QGridLayout is pushing everything into row column style. But I want to put the widgets whereever I want,Can anybody help me?
If you really want to set absolute positions, I would ignore using a layout altogether. You can manually set the positions of elements by using the move() function or the setGeometry() function.
QWidget *parent = new QWidget();
parent->resize(400, 400);
QPushButton *buttonA = new QPushButton(parent);
buttonA->setText("First Button");
buttonA->move(10, 10);
QPushButton *buttonB = new QPushButton(parent);
buttonB->setText("Second Button");
buttonB->move(15, 40);
Side note: I would avoid setting absolute positions of elements in Qt. Why? Well, Qt tries to be a platform-independent GUI library. On different platforms, a lot of display things can change (i.e. font size of text in push buttons) so the size of your actual push buttons can vary to accommodate large or smaller font sizes. This can throw off your meticulously spaced push buttons is you use absolute positions as in the example above.
If you use layouts, overlapping buttons or buttons falling off the edge of your window can be avoided.
You can see my answer for overlay button in QT: Qt Widget Overlays. This may help you to achieve what you want.