Render existing Qt Widget into SVG - qt

I have an exisiting Graph displayed as QWidget which I can already save to a bitmap using grab():
QPixmap image = grab();
Is there a Possibility to save that widget also to .svg?
Thanks!

QSvgGenerator generator;
generator.setFileName(path);
generator.setSize(widget->size());
generator.setViewBox(widget->rect());
generator.setTitle(tr("Your title"));
generator.setDescription(tr("some desscription"));
widget->render(&generator);

Related

How to save the QPixmap of a label which consist of one more label above it which has a Qpixmap

I have inherited the QLabel to create my own class of QLabel, The code is below:
class myLabel : public QLabel
{
Q_OBJECT
public:
explicit myLabel(QWidget *parent=nullptr): QLabel(parent){ setFrameShape(QFrame::Box);}
QLabel insideLabel;
};
As you can see, My class has one QLabel member inside.
Now, What I have done is that I created the object of my class and assign a image to it using setPixmap() and also assign a image to my QLabel member inside my class. The code is below:
QFile file("file.png");
ui->setupUi(this);
//Creatig instance of my QLabel class and setting one image to it.
myLabel *label=new myLabel(this);
label->setPixmap(QPixmap("someImagePath"));
//Assining image to my class QLabel member.
label->insideLabel.setPixmap(QPixmap("someImagePath"));
//saving file.
label->pixmap()->save("imageName","png",-1);
So when I save the image it only save the image of my QLabel class object QPixmap instead of saving both of my label image as the insideLabel is present above the my label class object as it is it's member. How can i save both images of my labels as one image.
Your code is not trying to save a QLabel, you are trying to save the pixmap property of a QLabel, those are two very different things.
A QLabel is a widget that can be rendered on a paint device. You should read the documentation about the QWidget subsystem:
Qt Widgets module
I see some problems with your code, the inside widget has no parent, and in your case I think that is a problem, but explaining that is beyond your question.
If what you want is to render the widget into an image file, you could do something like this:
QPixmap pixmap(Widget->size());
Widget->render(&pixmap);
pixmap.save("widget_render_file.png");
If you want to compose an image you can directly draw on a painter attached to a pixmap like this:
QPixmap pixmap(100,100);
QPainter painter(pixmap);
painter.setPen (...);
painter.drawPixmap (...);
painter.end();
pixmap.save(...);
You should also check documentation on QPainter and QPixmap, there's a lot of useful drawing/painting functions.
I just saved the needed portion of my Widget window as image, below is my code
label=new myLabel(this);
label->setGeometry(50,50,300,300);
label->setPixmap(QPixmap("/home/vinay/Pictures/exp.png").scaled(label->width(),label->height()));
label->insideLabel=new QLabel(this);
label->insideLabel->setGeometry(50,50,50,50);
label->insideLabel->setPixmap(QPixmap("/home/vinay/Pictures/exp2.png"));
label->insideLabel->setFrameShape(QFrame::Box);
label->insideLabel->setLineWidth(3);
//Assining image to my class QLabel member.
//saving file.
label->pixmap()->save("imageName","png",-1);
//ui->myWidget->grab().save("image.png");
QRect r(50,50,300,300);
Widget::grab(r).save("image.png");

set QGraphicsScene dynamically in QGraphicsView with OpenGL Viewport

I have a problem, i'm developing a graphical program under Windows, there are few QGraphicsScene and one QGraphicsView that it is possible to change the Scenes in runtime with a lot of graphics items, the problem is when I use Qwidget viewport everything works but when I switch to OpenGL viewport when I change the scene the content of previous scene still appear on the QGraphicsView and the contents of new Scene appear too.
what is the problem ? is it the changing Scenes method best solution or should I change the method ?
here is the code to setup View
m_viewPort = new QOpenGLWidget (this);
QSurfaceFormat format;
format.setProfile(QSurfaceFormat::CoreProfile);
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setSamples(4);
m_viewPort->setFormat(format);
ui->gV->setViewport(m_viewPort);
ui->gV->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
//ui->gV->setCacheMode(QGraphicsView::CacheBackground);
ui->gV->setRenderHints(QPainter::Antialiasing| QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform| QPainter::TextAntialiasing);
ui->gV->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->gV->setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
ui->gV->setTransformationAnchor(QGraphicsView::NoAnchor);
ui->gV->setAutoFillBackground(false);
ui->gV->setAttribute(Qt::WA_OpaquePaintEvent, true);
ui->gV->setAttribute(Qt::WA_NoSystemBackground, true);
resize(boardBaseSize);
here is code to set the new scene to the view
void GlScreenBoard::setShowScene(QGraphicsScene *scene, QString programName)
{
scene->setSceneRect(boardSceneRectBase);
ui->gV->setScene(scene);
}
another problem is when I set Graphics view CacheMode to CacheBackground the OpenGL viewport disables !! and the painter in QGraphicsScene returns to Raster !

QPixmap and SVG

How would you suggest to handle svg with QPixmap?
The construct QPixmap(":/myfile.svg"); then call of scaled() does not work. The QPixmap gets pixelised.
Thx.
Now there is much simpler way without needing of SVG module
QIcon("filepath.svg").pixmap(QSize())
So simple and works fine. Atleast in my case it worked.
You should use SVGRenderer to render it onto a QImage. From there you can convert to a QPixmap with QPixmap::convertFromImage.
Something like that:
QSvgRenderer renderer(svg_file_name);
QPixmap pm(width, height);
pm.fill(fill_color);
QPainter painter(&pm);
renderer.render(&painter, pm.rect());
On Qt5.12 i managed to display SVG icons without pixellisation in a QLabel:
QPixmap logoPixmap(":my-logo.svg"); // set your logo here
auto logoLabel = new QLabel(this);
logoLabel->setPixmap(logoPixmap);
logoLabel->setScaledContents(true);
logoLabel->setFixedSize(176, 61); // set your size here

How to set image on QPushButton?

I want to set an image on QPushButton, and the size of QPushButton should depend on the size of the image. I am able to do this when using QLabel, but not with QPushButton.
So, if anyone has a solution, then please help me out.
What you can do is use a pixmap as an icon and then put this icon onto the button.
To make sure the size of the button will be correct, you have to reisze the icon according to the pixmap size.
Something like this should work :
QPixmap pixmap("image_path");
QIcon ButtonIcon(pixmap);
button->setIcon(ButtonIcon);
button->setIconSize(pixmap.rect().size());
QPushButton *button = new QPushButton;
button->setIcon(QIcon(":/icons/..."));
button->setIconSize(QSize(65, 65));
You can also use:
button.setStyleSheet("qproperty-icon: url(:/path/to/images.png);");
Note: This is a little hacky. You should use this only as last resort. Icons should be set from C++ code or Qt Designer.
You may also want to set the button size.
QPixmap pixmap("image_path");
QIcon ButtonIcon(pixmap);
button->setIcon(ButtonIcon);
button->setIconSize(pixmap.rect().size());
button->setFixedSize(pixmap.rect().size());
I don't think you can set arbitrarily sized images on any of the existing button classes.
If you want a simple image behaving like a button, you can write your own QAbstractButton-subclass, something like:
class ImageButton : public QAbstractButton {
Q_OBJECT
public:
...
void setPixmap( const QPixmap& pm ) { m_pixmap = pm; update(); }
QSize sizeHint() const { return m_pixmap.size(); }
protected:
void paintEvent( QPaintEvent* e ) {
QPainter p( this );
p.drawPixmap( 0, 0, m_pixmap );
}
};
You can do this in QtDesigner. Just click on your button then go to icon property and then choose your image file.
This is old but it is still useful,
Fully tested with QT5.3.
Be carreful, example concerning the ressources path :
In my case I created a ressources directory named "Ressources" in the source directory project.
The folder "ressources" contain pictures and icons.Then I added a prefix "Images" in Qt So the pixmap path become:
QPixmap pixmap(":/images/Ressources/icone_pdf.png");
JF
Just use this code
QPixmap pixmap("path_to_icon");
QIcon iconBack(pixmap);
Note that:"path_to_icon" is the path of image icon in file .qrc of your project You can find how to add .qrc file here
In case anybody needs a PyQt version of the first answer:
class PictureButton(QAbstractButton):
def __init__(self, picture, parent):
super().__init__(parent)
self.setPicture(QPixmap(picture))
def setPicture(self, picture):
self.picture = picture
self.update()
def sizeHint(self):
return self.picture.size()
def paintEvent(self, e):
painter = QPainter(self)
painter.drawPixmap(0, 0, self.picture)

how to add an widget into the Form In QtDesigner

in qdesigner_workbench.cpp, how can I add a widget (say QLabel) into a FormWindow by code?
Since methods like createWidget()...etc are all abstract, how do I properly use the internal mechanics to add QLabel into the active FormWindow?
EDIT:
In qdesigner_workbench.cpp, this is currently what I have:
QDesignerFormWindowManagerInterface* fwm = core()->formWindowManager();
QDesignerFormWindowInterface* fw = fwm->activeFormWindow();
QWidget* mw = fw->mainContainer();
QLabel* label = new QLabel(mw); //can be added correctly but not in the right hierarchy
label->setText("I am a good girl.");
The mw (obtained from fw->mainContainer()) is actually a MainWindow, however the real data I need is in:
mw -> children[2] (which is a QDesignerWidget) -> children
There are 9 widgets in the designer, and you can see there's 9 arrays in children mentioned above; see this link (an image) for illustration.
http://img24.imagevenue.com/img.php?image=98871_a_122_476lo.jpg
So... how can I correctly add the QLabel widget?
Tried both
QLabel* label = new QLabel(fw); // will be a sibling of MainContainer, which is the QMainWindow (mw) in this case
QLabel* label = new QLabel(mw); // will be a sibling of QDesignerWidget
and apprarently either of the works.
If you want just to display a widget on a form, you can set your QMainWindow or QDialog to be the widget parent:
QLabel *l = new QLabel(this);
l->setText("My long string");
Where this is a pointer pointing to your current QDialog or QMainWindow.
Otherwise as ufukgun pointed out, you can use setCentralWidget if you need your widget to occupy the center of the QMainWindow.
You should add any QWidget to the QLayout of the form.This will put it into the display strategy of the form when resizing it.
form->ui->layout->add(yourQWidget);
Depending of the QLayout you are using, parameters of the add function will not be the same.
create a widget and add it to your main window as it is your central widget
mainWindow->setCentralWidget(centralWidget);
if you want to add a label, you can add it to this central widget

Resources