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.
Related
I am trying to draw various shapes like rectangle, ellipse, text etc uisng QGraphicsView and QGraphicsScene. For that I am trying to create an interface where there will be a vertical layout and besides that there will be few buttons. On clicking those buttons, I can show various QGraphicsItem's on screen. I want to create this interface programatically but not using ui.
I tried and ended up this way.
I wanted buttons on the right side and verticalLayout on the left side and both should filled up the whole screen.
Here is my current implementation :
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QGraphicsScene* scene = new QGraphicsScene(this);
QGraphicsView* view = new QGraphicsView(this);
view->setScene(scene);
QWidget* mainWidget = new QWidget(this);
QHBoxLayout *mainLayout = new QHBoxLayout();
QVBoxLayout *buttonLayout = new QVBoxLayout();
QVBoxLayout *vlayout2 = new QVBoxLayout();
vlayout2->addWidget(view);
QPushButton *btn1 = new QPushButton("Rectangle");
btn1->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
QPushButton *btn2 = new QPushButton("Ellipse");
btn2->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
QPushButton *btn3 = new QPushButton("Text");
btn3->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
buttonLayout->addWidget(btn1);
buttonLayout->addWidget(btn2);
buttonLayout->addWidget(btn3);
buttonLayout->addStretch();
mainLayout->addLayout(buttonLayout);
mainLayout->addLayout(vlayout2);
mainWidget->setLayout(mainLayout);
}
Can anyone guide me ?
Actually, it should work with the hints given in my comments.
I made an MCVE to convince myself:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QWidget qMain;
qMain.setWindowTitle("Test Box Layout");
qMain.resize(640, 320);
QHBoxLayout qHBox;
QVBoxLayout qVBoxBtns;
QPushButton qBtnRect("Rectangle");
qVBoxBtns.addWidget(&qBtnRect);
QPushButton qBtnCirc("Circle");
qVBoxBtns.addWidget(&qBtnCirc);
QPushButton qBtnText("Text");
qVBoxBtns.addWidget(&qBtnText);
qVBoxBtns.addStretch();
qHBox.addLayout(&qVBoxBtns);
QVBoxLayout qVBoxView;
QGraphicsView qView;
qVBoxView.addWidget(&qView, 1);
qHBox.addLayout(&qVBoxView, 1);
qMain.setLayout(&qHBox);
qMain.show();
// runtime loop
return app.exec();
}
Output:
Thus, there must be something else in OP's code…
Unfortunately, OP didn't expose an MCVE.
Thus, it's not clear how OP's Widget is instanced. Is it the widget which becomes the main window? Is there another widget where the Widget's instance becomes child of?
It's just guessing but the latter would explain what OP described.
To confirm my guess, I modified the above code a bit:
// setup GUI
QWidget qMain0; // main window widget
QWidget qMain(&qMain0); // child widget of main window widget
⋮
qMain.setLayout(&qHBox);
qMain0.show();
// runtime loop
return app.exec();
Please, note that qMain is now a child of qMain0 but there is no layout which adjusts the size of qMain when qMain0 is resized.
Hence, the size of view stays the initial size while the window is resized.
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();
}
I want to have some sequential actions; for example press a QPushButton and then delete the layout that is running and run another layout in the "SAME WINDOW"
In fact, I don't know what exactly layouts and widgets are!
Are they an object? an instance of object or what?
I found the bellow code in the Internet, I don't know how to change it to make it useful for me
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWidget *window = new Qwidget;
QPushButton *button1 = new QPushButton("One");
QPushButton *button2 = new QPushButton("Two"); QPushButton *button3 = new QpushButton("Three");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
window->setLayout(layout);
window->show();
return app.exec();
}
A better way than deleting layout and setting a new one would be to use a QStackedWidget (docs) and the concept of pages. Using QStackedWidget you can show and hide pages as you wish.
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);
I am trying to add a label to the main window using Qt. Here is a piece of the code:
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWidget Main_Window;
QPixmap Image;
Image.load("1837.jpg");
QLabel i_label;
i_label.setPixmap(Image);
i_label.show();
QPushButton Bu_Quit("Quit", &Main_Window);
QObject::connect(&Bu_Quit, SIGNAL(clicked()), qApp, SLOT(quit()));
Main_Window.show();
return app.exec();
}
I've been having a very hard time figuring out how to properly add QLabels to QWidgets, I tried to set the Main_Window as the main widget using this method: app.setMainWidget(Main_Window) and the label was still outside the window. So how do I put labels into widgets using Qt?
hamza, this code worked fine for me:
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget Main_Window;
QLabel i_label("Start", &Main_Window);
//i_label.setPixmap(QPixmap("1837.jpg"));
QPushButton Bu_Quit("Quit" , &Main_Window);
QObject::connect(&Bu_Quit , SIGNAL(clicked()), qApp , SLOT(quit()));
QVBoxLayout *vbl = new QVBoxLayout(&Main_Window);
vbl->addWidget(&i_label);
vbl->addWidget(&Bu_Quit);
Main_Window.show();
return app.exec();
}
I commented setting the image code to show you that the label was set correctly. Make sure your image is valid (otherwise you won't see the text). The trick here was that you need to use qt layouts like QVBoxLayout
Add the label to a layout widget and set the window layout to that layout.
Design note: its better to create your own MainWindow class, inheriting from QMainWindow for instance, and design it from the inside.
or even better, use QtCreator.
You can try:
QWidget window;
QImage image("yourImage.png");
QImage newImage = image.scaled(150, 150, Qt::KeepAspectRatio);
QLabel label("label", &window);
label.setGeometry(100, 100, 100, 100);
label.setPixmap(QPixmap::fromImage(newImage));
window.show();
this way you can even decide where to put the label and choose the image size.