I would like to put an svg image as background to my QGraphicsView without repetition and preserving the ratio. Can you help me?
Thanks.
This is one Example :
First of all add QT += svgwidgets in your .pro.
then add one graphicsView in your UI File :
in mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QGraphicsScene>
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow: public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QGraphicsScene *scene;
};
#endif // MAINWINDOW_H
in mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsSvgItem>
#include <QSvgRenderer>
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QGraphicsScene(this);
ui->graphicsView->setScene(scene);
QGraphicsSvgItem *item = new QGraphicsSvgItem(":/images/images/diagramTool.svg");
scene->addItem(item);
}
MainWindow::~MainWindow()
{
delete ui;
}
output :
And there is one easy way you can add this stylesheet in your graphics view :
background-image: url(":/images/images/diagramTool.svg");
background-repeat: no-repeat;
background-position: center;
border-style:none;
This will add SVG as your background image.
To put a background that fits the size of the object I created a class that inherits from QGraphicsScene and I rewrote drawBackground by putting my svg image in it.
myscene.h
class myscene : public QGraphicsScene
{
public:
myscene();
~myscene();
void drawBackground(QPainter *painter, const QRectF &rect);
};
myscene.cpp
myscene::myscene():QGraphicsScene()
{
}
myscene::~myscene()
{
}
void myscene::drawBackground(QPainter *painter, const QRectF &rect)
{
painter->drawImage(rect, QImage(":myPathImage.svg"));
}
Then in my QGraphicsView I passed it this scene and it works.
myview.h:
class myview : public QGraphicsView
{
private :
myscene* _scene;
public:
myview();
~myview();
};
myview.cpp:
myview::myview() : QGraphicsView()
{
_scene = new myscene();
this->setScene(_scene);
this->showMaximized();
}
myview::~myview()
{
delete _scene;
}
Related
So, I have the source code for a training. Where I want to do operation with QGraphicsView named pp in the own class ProcessPicture.
I would ask you, is it possible to put the QGraphicsView object to the method of own class? If yes, please tell me how or lead me on answer.
For a detailed description after releasing button will done the on_processPic_pushButton_released() where is called the method of pp object. This method take a ui->graphicsview as argument. This argument will used in the pp.drawrectangle(ui->graphicsview).
The code is without error or warning, only it is not draw the rectangle to the ui->graphicsview. When I take a source code from pp.drawrectangle() and try it, in the on_processPic_pushButton_released() all is fine. So I think that i miss some knowledge.
Lets look on my source code.
processpicture.h
#ifndef PROCESSPICTURE_H
#define PROCESSPICTURE_H
#include "QString"
#include "QPicture"
#include "QGraphicsView"
class ProcessPicture
{
public:
ProcessPicture();
void draw(QGraphicsView out);
void draw_rectangle(QGraphicsView out);
private:
QString path = "***/Untitled.bmp";
QImage img;
};
#endif // PROCESSPICTURE_H
processpicture.cpp
#include "processpicture.h"
#include "QGraphicsScene"
#include "QGraphicsPixmapItem"
ProcessPicture::ProcessPicture()
{
img.load(path);
}
void ProcessPicture::draw_rectangle(QGraphicsView out){
//QGraphicsScene* scene = new QGraphicsScene();
QGraphicsScene scene;
QRect rect;
rect.setRect(10,10,10,10);
scene.addRect(rect);
out.setScene(&scene);
out.show();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "processpicture.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
ProcessPicture *pp;
//pp = new ProcessPicture;
~MainWindow();
private:
private slots:
void on_processPic_pushButton_released();
private:
Ui::MainWindow *ui;
bool event(QEvent *event);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
pp = new ProcessPicture;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_processPic_pushButton_released()
{
//pp->draw(ui->graphicsView);
pp->draw_rectangle(ui->graphicsView);
}
For every non-toxic answer I thank.
I've been trying to create a frame to be shown as a tooltip, but be functionally different. It's got to be shown at a certain point, floating, to be called from a delegate.
Now, if I don't pass a parent it's seen but yeah, it's detached.
And I want it to be windowless.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QDebug>
#include <QFrame>
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSize size { 350, 550 };
QPoint topLeft { 550, 550 };
auto* frame = new QFrame(this); // this is a QWidget
frame->setGeometry({ topLeft, size });
frame->show();
frame->activateWindow();
frame->raise();
qInfo() << frame->isVisible(); // returns true
}
MainWindow::~MainWindow()
{
delete ui;
}
Any suggestions?
I try to switch between two different Widgets in QT5.
The first problem was that my first window was visible in the background of my second window. I solve this with a check in "autoFillBackground". Now i can switch between them, but if i resize them it only resize the Main content.
Both Widgets have a grid layout.
Resize Problem
Im new at QT5, so is there a better way to make a switching between 2 widgets without this problem?
I try it with wMessages = new Messages(); and hide() but then my program crash after going back.
Code:
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "messages.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_btnMessages_clicked();
private:
Ui::MainWindow *ui;
Messages *wMessages;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnMessages_clicked()
{
wMessages = new Messages(this);
wMessages->show();
}
messages.h:
#ifndef MESSAGES_H
#define MESSAGES_H
#include <QWidget>
namespace Ui {
class Messages;
}
class Messages : public QWidget
{
Q_OBJECT
public:
explicit Messages(QWidget *parent = nullptr);
~Messages();
QString NewsGenerator();
private slots:
void on_bBack_clicked();
void on_pushButton_clicked();
private:
Ui::Messages *ui;
};
#endif // MESSAGES_H
messages.cpp:
#include "messages.h"
#include "ui_messages.h"
Messages::Messages(QWidget *parent) :
QWidget(parent),
ui(new Ui::Messages)
{
ui->setupUi(this);
}
Messages::~Messages()
{
delete ui;
}
void Messages::on_bBack_clicked()
{
this->close();
QWidget *parent = this->parentWidget();
parent->show();
}
Edit 1 - working Main Window Button (from G.M.´s answer):
void MainWindow::on_btnMessages_clicked()
{
wPlaner = new Planer();
QMainWindow::setCentralWidget(wPlaner);
}
Update (based on the comments):
The best solution was to use the QStackedWidget to navigate between the views.
Docu: https://doc.qt.io/qt-5/qstackedwidget.html#details
Example-Code for Button:
// return back to first view
void MainWindow::on_btnret_clicked()
{
ui->stackedWidget->setCurrentIndex(0);
}
I would like to have the tool icons at the right side, rather than at the top. As I experienced, I can move them manually, I can set their orientation() to vertical, but they remain at the top; I can set setAllowedAreas() which means I restrict where the toolbar areas can reside, but the tool buttons reside at the top. I need something like setToolbarArea(). Is there something similar?
You can call addToolBar again to move the toolbar.
According to the documentation,
If the main window already manages toolbar then it will only move the
toolbar to area.
I.e.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QToolBar * toolBar;
public slots:
void moveLeft();
void moveRight();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
toolBar= new QToolBar("Tool Bar");
toolBar->addAction(QIcon(":/qt.png"), "FirstAction", this, SLOT(moveLeft()));
toolBar->addAction(QIcon(":/qt.png"), "SecondAction", this, SLOT(moveRight()));
addToolBar(Qt::RightToolBarArea, toolBar);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::moveLeft()
{
addToolBar(Qt::LeftToolBarArea, toolBar);
}
void MainWindow::moveRight()
{
addToolBar(Qt::RightToolBarArea, toolBar);
}
I am trting to open a new window (window with the cubeview view in qt3d application) whenever a button is clicked on the main window.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "cubeview.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
int getid();
public slots:
void pattern1();
private:
CubeView *view;
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
and mainwindow .cpp file
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <iostream>
#include "cubeview.h"
int pattern_id;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPushButton *button= new QPushButton("Pattern 1");
QObject::connect(button, SIGNAL(clicked()), this, SLOT(pattern1()));
button->show();
std::cout<<"reached mainwindow constructor"<<std::endl;
//view= new CubeView;
}
void MainWindow::pattern1()
{
pattern_id=1;
view->begin(1);
view->resize(800, 600);
view->show();
std::cout<<pattern_id<<std::endl;
}
int MainWindow::getid()
{
return pattern_id;
}
MainWindow::~MainWindow()
{
delete ui;
delete view;
}
I get a runtime error.
I hope you get what i am trying to do. Whenever i click on the push button, the cubeview view window should show up. What is the mistake i am making?
Where should I define the cubeView class object so that I can use it later.
Can I initialize it as CubeView *view= new CubeView; in a header file.
I tried to write it in the constructor of mainwindow.cpp
but i get a runtime error.
#ifndef CUBEVIEW_H
#define CUBEVIEW_H
#include "qglview.h"
#include "qgltexture2d.h"
QT_BEGIN_NAMESPACE
class QGLSceneNode;
QT_END_NAMESPACE
//! [1]
class CubeView : public QGLView
{
//! [1]
Q_OBJECT
public:
CubeView(QWidget *parent = 0);
~CubeView();
void begin(int pattern_id);
public slots:
void update_action();
protected:
void paintGL(QGLPainter *painter);
//! [2]
private:
QGLSceneNode *cube;
QGLSceneNode *cursor;
QGLTexture2D logo;
QGLTexture2D* texture;
QGLTexture2D handcursor;
};
//! [2]
#endif
//! [1] constructor, initialize the cube, cursor and camera
CubeView::CubeView(QWidget *parent)
{
//! [1] draw the paintboard
QVector3D *cube1_pos= new QVector3D(0.0,0.0,-1.5);
QGLBuilder builder1;
builder1 << QGL::Faceted;
builder1 << QGLCube(3.25);
cube = builder1.finalizedSceneNode();
cube->setPosition(*cube1_pos);
//draw the cursor
QGLBuilder cursor_builder;
cursor_builder <<QGL::Faceted;
cursor_builder <<QGLCube(0.15);
cursor=cursor_builder.finalizedSceneNode();
//camera setup
camera()->setFieldOfView(35);
camera()->setNearPlane(1);
camera()->setFarPlane(15);
//! [2] set texture for cube and cursor
//QImage image(QLatin1String(":/bluecircle.jpg"));
handcursor.setImage(QImage(QLatin1String(":/hand.jpg")));
std::cout<<"constructor called"<<std::endl;
}
I think I finally found my answer. It has nothing to to do with the definition of the cubeview class constructor. The simple principle is that
-> we need not create a class object within a loop or the program code crashes.
-> also the view.show if directly put inside a connect slot , will run into the error of an infinite loop.
Here is the answer.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <iostream>
#include "cubeview.h"
int pattern_id;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
view=0;
std::cout<<"reached mainwindow constructor"<<std::endl;
QPushButton *button= new QPushButton("Pattern 1");
QObject::connect(button, SIGNAL(clicked()), this, SLOT(pattern1()));
button->show();
else if(view!=NULL)
{
std::cout<<"view is already initialized"<<std::endl;
}
}
void MainWindow::pattern1()
{
if(view==NULL)
{
view=new CubeView;
view->begin(1);
view->resize(800, 600);
view->show();
}
}
int MainWindow::getid()
{
return pattern_id;
}
MainWindow::~MainWindow()
{
delete ui;
delete view;
}
In this way, the new object window is created if the value is already NULL.