QGraphicsScene many widgets - c++

I have more than one widget in QGraphicsScene. The first created widget is on top of scene, other widgets is under first widget. I want such functionality - if i press one of widget it will be on top of the scene. How i can make it?
Also i don't know, how to make border to the widget in QGraphicsScene like the normal widget. This is the code:
QGraphicsScene *scene ;
QGraphicsProxyWidget *pw()
{
QWidget *w = new QWidget;
w->resize(580, 280);
w->setStyleSheet("background-color: rgb(110, 149, 255)");
QPushButton *p = new QPushButton;
p->setParent(w);
p->move(30, 50);
p->setText("hello");
QPushButton *p2 = new QPushButton;
p2->setParent(w);
p2->move(110, 50);
p2->setText("world");
QGraphicsWidget *parentWidget = new QGraphicsWidget();
parentWidget->setMinimumSize(QSizeF(100, 30));
parentWidget->setFlags(QGraphicsItem::ItemIsMovable);
parentWidget->setAutoFillBackground(true);
parentWidget->resize(580, 280);
scene->addItem(parentWidget);
QGraphicsProxyWidget *proxyWidget = new QGraphicsProxyWidget;
proxyWidget->setWidget(w);
proxyWidget->setParentItem(parentWidget);
return proxyWidget;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
scene = new QGraphicsScene;
scene->setSceneRect(0, 0, 800, 480);
scene->addItem(pw());
scene->addItem(pw());
scene->addItem(pw());
scene->setBackgroundBrush(Qt::darkGreen);
QGraphicsView view(scene);
view.show();
return a.exec();
}

Related

Change vertical header title

How I can change title shown on the picture to "№". Thanks.
That widget is an object of the QTableCornerButton class that inherits from QAbstractButton but it is a class that is part of the private Qt API that does not use text, so you can not use setText() of QAbstractButton, so the other option is establish a QLabel with a layout above:
#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTableView w;
QStandardItemModel model(10, 10);
w.setModel(&model);
QAbstractButton *button = w.findChild<QAbstractButton *>();
if(button){
QVBoxLayout *lay = new QVBoxLayout(button);
lay->setContentsMargins(0, 0, 0, 0);
QLabel *label = new QLabel("№");
label->setContentsMargins(0, 0, 0, 0);
lay->addWidget(label);
}
w.show();
return a.exec();
}

QT Display a QWidget above QGraphicsScene

Currently I have a QGraphicsScene that is put inside a QGraphicsView and is shown on the display. I add all my elements to my scene that I set as the active scene.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsView w;
GameScene *gameScene = new GameScene(); // GameScene extends QGraphicsScene, adds tons of elements to the scene
w.setScene(gameScene);
w.show();
return a.exec();
}
Above this scene I want a bar that contains several layout elements, like several QProgressBar.
For what I have found so far, QWidget's can be positioned easily. I've made already a widget of what I need to be displayed above the scene:
QWidget *dummyWidget = new QWidget();
QFormLayout *formLayout = new QFormLayout;
QProgressBar *bar1 = new QProgressBar();
QProgressBar *bar2 = new QProgressBar();
bar1->setValue(20);
bar2->setValue(100);
formLayout->addRow("&Health:", bar1);
formLayout->addRow("&Energy:", bar2);
dummyWidget->setLayout(formLayout);
dummyWidget->show();
But how do I get this to be displayed above my QGraphicsScene?
If you want to display your widget above the view you can have a layout similar to the one for dummyWidget and add the widget and view in it :
QGraphicsView w;
QWidget *widget = new QWidget();
QFormLayout *formLayout2 = new QFormLayout(widget);
QWidget *dummyWidget = new QWidget();
QFormLayout *formLayout = new QFormLayout;
QProgressBar *bar1 = new QProgressBar();
QProgressBar *bar2 = new QProgressBar();
bar1->setValue(20);
bar2->setValue(100);
formLayout->addRow("&Health:", bar1);
formLayout->addRow("&Energy:", bar2);
dummyWidget->setLayout(formLayout);
formLayout2->addRow("", dynamic_cast<QWidget*>(dummyWidget));
formLayout2->addRow("", dynamic_cast<QWidget*>(&w));
widget->show();
If you want to add the widget in the scene, you can use QGraphicsScene::addWidget which creates a new QGraphicsProxyWidget for widget, adds it to the scene, and returns a pointer to the proxy :
QGraphicsProxyWidget * item = gameScene->addWidget(dummyWidget);
item->setPos(100,100);
item->setZValue(1);
You can also add it to an item :
item->setParentItem(anOtherItem);

QLabel takes complete space

I have a QWidget which contains a QVBoxLayout and that layout contains a QLabel and QToolButtons. My problem is, that the QLabel takes all the space. The only solution I found is to set maximumHeight to the QLabel, but if I do that, the Qt::AlignTop doesn't work anymore.
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget window_main;
QWidget *widget_steps = new QWidget(&window_main);
widget_steps->setFixedWidth(75);
widget_steps->move(QPoint(0, 0));
widget_steps->setStyleSheet("background-color: red;");
QVBoxLayout *layout_steps = new QVBoxLayout(widget_steps);
layout_steps->setContentsMargins(0, 0, 0, 0);
layout_steps->setSpacing(0);
QLabel *label_steps_start = new QLabel("steps:");
label_steps_start->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
label_steps_start->setStyleSheet("background-color: blue;");
layout_steps->addWidget(label_steps_start);
QToolButton *tbutton_step1 = new QToolButton();
layout_steps->addWidget(tbutton_step1);
QToolButton *tbutton_step2 = new QToolButton();
layout_steps->addWidget(tbutton_step2);
QToolButton *tbutton_step3 = new QToolButton();
layout_steps->addWidget(tbutton_step3);
window_main.showMaximized();
return a.exec();
}
Here a picture that shows how much space the QLable takes(the blue space):
So please help to minimize the space the QLable takes :)
Your problem is that the tool buttons have a fixed size, and therefore when resizing, the label is the only type that can grow: Therefore:
After adding the label, add stretch to the layout:
layout_steps->addWidget(label_steps_start);
layout_steps->addStretch();
Modified code - adds stretch at the bottom. Label size remains fixed, and buttons remain under it. I've removed the whole main window around the outside for the sake of testing.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *widget_steps = new QWidget;
widget_steps->setFixedWidth(75);
widget_steps->move(QPoint(0, 0));
widget_steps->setStyleSheet("background-color: red;");
QVBoxLayout *layout_steps = new QVBoxLayout(widget_steps);
layout_steps->setContentsMargins(0, 0, 0, 0);
layout_steps->setSpacing(0);
QLabel *label_steps_start = new QLabel("steps:");
label_steps_start->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
label_steps_start->setStyleSheet("background-color: blue;");
layout_steps->addWidget(label_steps_start);
//--- Removed.... layout_steps->addStretch();
QToolButton *tbutton_step1 = new QToolButton();
layout_steps->addWidget(tbutton_step1);
QToolButton *tbutton_step2 = new QToolButton();
layout_steps->addWidget(tbutton_step2);
QToolButton *tbutton_step3 = new QToolButton();
layout_steps->addWidget(tbutton_step3);
layout_steps->addStretch(); //<----- Added!
widget_steps->show();
return a.exec();
}
One way you could do is to set the stretch factor for that particular widget inside the QVBoxLayout. You can find the documentation for that in here.
Basically, when you add a widget you can set that, for instance:
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QToolButton>
#include <QtWidgets/QVBoxLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget window_main;
QWidget *widget_steps = new QWidget(&window_main);
widget_steps->setFixedWidth(75);
widget_steps->move(QPoint(0, 0));
widget_steps->setStyleSheet("background-color: red;");
QVBoxLayout *layout_steps = new QVBoxLayout(widget_steps);
layout_steps->setContentsMargins(0, 0, 0, 0);
layout_steps->setSpacing(0);
QLabel *label_steps_start = new QLabel("steps:");
label_steps_start->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
label_steps_start->setStyleSheet("background-color: blue;");
layout_steps->addWidget(label_steps_start, 3, Qt::AlignTop);
layout_steps->addStretch();
QToolButton *tbutton_step1 = new QToolButton();
layout_steps->addWidget(tbutton_step1, 1);
QToolButton *tbutton_step2 = new QToolButton();
layout_steps->addWidget(tbutton_step2, 1);
QToolButton *tbutton_step3 = new QToolButton();
layout_steps->addWidget(tbutton_step3, 1);
window_main.showMaximized();
return a.exec();
}

Creating transparent QPixmap

I am using QPainter on QPixmap as the painting framework. And QGraphicsScene is holding the QPixmap. The painting works well. But the problem is when I change the the background-color of the QGraphicsView it does not get reflected on the screen. I tried by QPixmap::fill(Qt::tranparent). But it didnt work.
How can I achieve this kind of transparent QPixmap?
Thanx in advance?
int main(int argc, char **argv){
QApplication a(argc, argv);
QMainWindow *win = new QMainWindow();
win->resize(600,600);
win->move(80,80);
win->show();
QGraphicsScene *scene = new QGraphicsScene(win);
QGraphicsView view(scene,win);
view.resize(590,590);
view.setBackgroundBrush(QColor(rand()%255,rand()%255, rand()%255, 255));
view.show();
QPixmap *pix = new QPixmap(600,600);
pix->fill(&view,QPoint(0,0));
QGraphicsPixmapItem *item = scene->addPixmap(*pix);
QPainter *painter = new QPainter(pix);
int count=10;
while(count){
painter->setPen((*new QColor(rand()%255,rand()%255, rand()%255, 255)));
painter->setBrush(QColor(rand()%255,rand()%255, rand()%255, 255));
painter->drawRect(rand()%300, rand()%300, rand()%300, rand()%300);
item->setPixmap(*pix);
a.processEvents(0x00);
count--;
}
return a.exec();
}

Qt Framework: How to display a QGraphicsView in a layout?

I am having trouble getting a QGraphicsView to show up in a QVBoxLayout object and I have no idea what is wrong. My code compiles so no errors are being thrown. Here is my simple code. (I am a Qt and C++ newb). At the bottom, I add a QPushButton widget to the layout and that shows up fine. Thanks for your help in advance!
QGraphicsScene scene;
QGraphicsView view(&scene);
view.setBackgroundBrush(QImage(":/images/bg/tile.png"));
view.setCacheMode(QGraphicsView::CacheBackground);
QPixmap pixmap("images/icons/dsp.gif");
QGraphicsPixmapItem* dsp = scene.addPixmap(pixmap);
view.show();
vlayout->addWidget(&view);
vlayout->addWidget(new QPushButton("some button here"));
Not enough context, so I can't tell what's happening exactly. But, if those are in a function, then you are declaring local variables that are gone once the function exits. If you are in the main, you're code should look something like this, but it will probably crash:
QApplication app(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
QWidget widget;
view.setBackgroundBrush(Qt::red);
QVBoxLayout vlayout;
widget.setLayout(&vlayout);
vlayout.addWidget(&view);
vlayout.addWidget(new QPushButton("some button here"));
widget.show();
I recommend dynamically allocating objects:
int main(int argc, char* argv[]){
QApplication app(argc, argv);
QGraphicsScene* scene = new QGraphicsScene;
QGraphicsView* view = new QGraphicsView(scene);
QWidget *widget = new QWidget;
view->setBackgroundBrush(Qt::red);
QVBoxLayout* vlayout = new QVBoxLayout(widget);
vlayout->addWidget(view);
vlayout->addWidget(new QPushButton("some button here"));
widget->show();
return app.exec();
}
Don't forget to delete the parent object so it doesn't leak memory.