Displaying a Pixmap on a Graphics View Widget Object in Qt - qt

I am trying to display a pixmap on the Graphic View widget. I believe what it is missing is a way to actually link the QGraphicsScene "scene" to the widget I have on the form, seeing that you can create multiple Graphics View Objects there must be a way to explicitly state which Graphics View item you want the pixmap to be displayed on. The Graphics View widget object is called PixMapView, using the same name as my GraphicsView object in my code did not change the functionality of my program. The code below compiles but just shows a blank white Graphics View object. My goal is to create a diagonal line on the pixmap and display it on the Graphics View Object. Previously the first section of code, all the way to the start of the while loop, worked with fillRect and some Auto-fill backround code. I believe the problem is purely in the section of code after the while loop *The while loop is essentially the only part not from Qt documentation. So in short could someone look at this code and see why my pixmap is not displaying on my Graphics View Widget.
CanvasTest::CanvasTest(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::CanvasTest)
{
ui->setupUi(this);
QPixmap pm(200,200);
QPainter pmp(&pm);
pmp.setPen(Qt::black);
int counter = 0;
while (counter < 200)
{
pmp.drawPoint(counter,counter);
counter++;
}
pmp.end();
QGraphicsScene scene;
QGraphicsPixmapItem item(pm);
scene.addItem(&item);
QGraphicsView view(&scene);
view.show();
}
What the form looks like with the Graphic View Widget
I would like to display the diagonal line on the widget presented in the image

ui->(whatever name your widget has)->( any method your widget is associated with)
Note: this is due to the automatic code ui->setupUI(this);

Related

Using QML with a qt widgets type of ui form?

So I would like to create an Application which looks something like this:
What this application does is, I can select shapes through the combobox on the left and put them on the Area to the right. With the slider I can vary the sizes. The checkboxes select a border or make the shape have a filling color.
My Problem is I would like to create these shapes through using QML, as its relatively easy to create such basic shapes with rectangle, circle etc. ,however I would also like to have the nice interface seen on the left. Is this possible with QML only or do I need to integrate QML into qtwidgets or something like that? I know that there is a slider and a button also present in QML, which look perfectly fine but I would like to have a clear area on the right which indicates to the user where he can create shapes and the ui stuff on the left. What is the correct approach here?
For the drawing part of your app, using QGraphicsScene https://doc.qt.io/qt-5/qgraphicsscene.html could also be an alternative to stay with Qt Widget instead of mixing it with QML.
But if you want to stick with QML you can look at QQuickView https://doc.qt.io/qt-5/qquickview.html and here is a small example of integration :
#include <QQuickView>
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ..
QQuickView *view = new QQuickView;
QWidget *container = QWidget::createWindowContainer(view, this);
// some set up if needed
container->setMinimumSize(1280, 600);
container->setMaximumSize(1280, 600);
container->setFocusPolicy(Qt::TabFocus);
// ..
view->setSource(QUrl("main.qml"));
view->setResizeMode(QQuickView::SizeViewToRootObject);
ui->verticalLayout->addWidget(container);
// ..
}
I highly recommend using QML for the entire UI. Firstly, Qt Quick and QWidgets are completely different UI engines. I find markup based UI easier to source control, adjust, and generally work with. Furthermore, Qt Quick and QML is the best UI framework I've ever used, and there have been many. You can easily do everything you want.

Rendering QML over another window using QWidget

I am currently using QWidget to embed a window from another library (Panda3D). I've been trying to see if it was possible to add a QML-based interface to Panda3D by rendering a QQuickView over the QWidget containing Panda3D's window.
When I don't initialize Panda3D, I can see my QQuickView being properly rendered over the widget: but when I do reparent Panda3D's window to the widget, then the window is rendered over the QQuickView.
I'd like to know if what I'm trying to do is possible, and if yes, how would I do such a thing ?

Is a QGraphicsSceneEvent::widget() always a QGraphicsView?

According to the docs, QGraphicsSceneEvent::widget() returns a QWidget. Isn't the widget always going to be a QGraphicsView, though (or null)?
I would assume so, except then I don't understand why the devs wouldn't have just made it QGraphicsSceneEvent::view().
The reason I'm asking is that in my subclassed QGraphicsScene, I have overridden QGraphicsScene::mousePressEvent() and I want to know which view originated the event--I'm wondering if it's safe to static cast widget() to a QGraphicsView, or if it's conceivable that some other widget could have created the event.
As it turns out, QGraphicsSceneEvent::widget() returns the viewport widget, not the QGraphicsView. If you want the QGraphicsView, you would need to use: event->widget()->parent().
Documentation page you refered mentions the QGraphicsView as a target of events:
When a QGraphicsView receives Qt mouse, keyboard, and drag and drop
events (QMouseEvent, QKeyEvent, QDragEvent, etc.), it translates them
into instances of QGraphicsSceneEvent subclasses and forwards them to
the QGraphicsScene it displays. The scene then forwards the events to
the relevant items.
However, if you doubt that QGraphicsSceneEvent::widget() always returns QGraphicsView, or you relay that it should always be a QGraphicsView you can check that by using qobject_cast:
QGraphicsView *view = qobject_cast<QGraphicsView *>(event->widget();
if (view) {
// Handle the event
} else {
// This is something that I do not expect.
// ..
}

Show 2 Windows at Same time in Qt

How can i show two windows at same time ? Well i have a mainwindow ,then when i press a button i load a plugin which creates and return a qwidget, and set it as central widget setCentralWidget() ,but my app crashes .If i'm not wrong this anyway will show just one window at same time .
Code from plugin :
QWidget* PlPlugin::initPltter() {
plotter = new QWidget();
plotter->resize(200,300);
plotter->setWindowTitle("mypl");
plotter->show();
return plotter;
}
In my app i'm doing :
setCentralWidget(plotter->initPlotter());
Try not resizing or showing it. Its unnecessary if its going to become a central widget of the mainwindow.
Also, from your example there is nothing suggesting that you are trying to show two windows. What you are doing is creating another widget and setting it as a child of the main window. Do one or the other: Create the widget and show it directly, or create it and parent it under another.
Your MainWindow child shown in main.cpp, for second widget do this:
QWidget* PlPlugin::initPltter() {
plotter = new QWidget();
plotter->resize(200,300);
plotter->setWindowTitle("mypl");
plotter->show();
return plotter;
}
And don't do this
setCentralWidget(plotter->initPlotter());
It allow you to get MainWindow and widget in separate 'window'

How to show QGLWidget in full screen?

I have a QGLWidget as part of the UI of my application. It is NOT a central widget, there are a lot of others widgets around it. I want to show it full screen on user clicks the button. Similar functionality like on youtube video flash player.
I have tried to use showFullScreen with no effect.
I have read how-to-fullscreen-a-qglwidget and fullscreen-widget, but they suggest using showFullScreen.
Qt documentation states that for using showFullScreen widget must be an independent window. So I assume there should be some trick for this.
The solution I found:
void MyApp::on_fullscreen_button_clicked() {
QDialog *dlg = new QDialog(this);
QHBoxLayout *dlg_layout = new QHBoxLayout(dlg);
dlg_layout->setContentsMargins(0, 0, 0, 0);
dlg_layout->addWidget(glwidget_);
dlg->setLayout(dlg_layout);
dlg->showFullScreen();
bool r = connect(dlg, SIGNAL(rejected()), this, SLOT(showGlNormal()));
assert(r);
r = connect(dlg, SIGNAL(accepted()), this, SLOT(showGlNormal()));
assert(r);
}
void MyApp::showGlNormal() {
ui.glBox->layout()->addWidget(glwidget_);
}
The showFullScreen function works only on windows. From the Qt documentation:
A window is a widget that isn't visually the child of any other widget
and that usually has a frame and a window title.
A possible solution is the following:
When the user clicks the show full screen button
Create a new QGlWidget with no parent and set to it the contents of you QGlWidget
Use the showFullScreen function on it...
Maybe it is a better idea to subclass QGlWidget and pass in its constructor a pointer to another QGlWidget. The constructor should take the context of the provided widget and apply it to the new one.
On your subclass catch keyboard events. When the user press Esc emit a signal
In your base class catch this signal and connect it to a slot. In this slot hide the full screen QGlWidget and delete it.

Resources