QT: picture as window - c++

I want to make window frame using some picture. Window shouldn't have borders, titlebars, etc. It also should be hidden from active windows list (in taskbar).
Second part of question I did with:
this->setAttribute(Qt::WA_NoSystemBackground);
this->setAttribute(Qt::WA_QuitOnClose);
this->setAutoFillBackground(true);
this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
for new class which inherits QMainWindow. It's hidden, for example, at gnome taskbar, but in Awn (awant windows navigator) I seed it in the list of active windows :(.
What about first part. I did this some time ago with QRegion, QPixmap and mask in overloaded paintEvent. I've lost the code. Can you help me with this?

regarding the first part of the question, you, probably, looking for smth like this:
void MainWindow::paintEvent(QPaintEvent * event)
{
QPainter painter(this);
QPixmap pixmap = QPixmap();
pixmap.load("/home/my_image.jpg");
painter.drawPixmap(event->rect(), pixmap);
}
as an alternative you can create a label and show it on your main window, smth like this:
QLabel* label = new QLabel(this); // where 'this' is your window
label->setGeometry(this->geometry());
QPixmap pixmap = QPixmap();
pixmap.load("/home/my_image.jpg");
label->setPixmap(pixmap.scaled(label->size(), Qt::KeepAspectRatio));
hope this helps, regards

Related

Render QWidget in QPixmap with system background

When I render a QWidget with a QOpenGLWidget child with transparency objects, I observe a solarization effect when I tried to take a screenshot like the following picture:
The problem comes with the system background because when I remove it, the problem disappear:
.
My question is: What is the solutions to render a QWidget on a QPixmap with the system background?
Here my render code:
QWidget widget;
QPixmap pixmap(widget.size());
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
widget.render(&painter, QPoint(), QRegion(), QWidget::DrawWindowBackground /* the problem is this render flag */ | QWidget::IgnoreMask | QWidget::DrawChildren);
pixmap.save("screenshot.png");
The property setAutoFillBackground(true); and the method grab(); do the same like the first screenshot.
EDIT: There is no OpenGL problem. When I mix two pixmaps (the first with the background and the second with widget children), the solarization problem is still present.
A solution is to set a QPalette with Window role to black in my QOpenGLWidget.
QPalette currentWidgetPalette{ palette() };
currentWidgetPalette.setColor(QPalette::Window, Qt::black);
setPalette(currentWidgetPalette);
EDIT: I found a solution to paint destination in tansparent and source with my widget to compose the pixmap correctly.
painter.setCompositionMode(QPainter::CompositionMode_Destination);
painter.fillRect(result.rect(), Qt::transparent);
painter.setCompositionMode(QPainter::CompositionMode_Source);
widget.render(&painter, QPoint(), QRegion(), QWidget::DrawWindowBackground | QWidget::IgnoreMask | QWidget::DrawChildren);

QT: shaded window effect (lights out)

I'm opening a modal window from my main window and my interest is to make the background dark so the top window is perfectly visible but the main one looks dark like in the "shade".
You can show some half-transparent widget over the mainwindow and it will create shadow effect.
For example, such widget.
class Overlay : public QWidget
{
public:
Overlay(QWidget *parent) {
setPalette(Qt::transparent);
setAttribute(Qt::WA_TransparentForMouseEvents);
}
protected:
void paintEvent(QPaintEvent *event) {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(QBrush(QColor(0,0,0, 150)));
painter.setPen(Qt::NoPen);
painter.drawRect(rect());
}
};
Then create this widget, resize and show:
overlay_.reset(new Overlay(this));
overlay_->resize(size());
overlay_->setVisible(true);
You can play with the shadow color and transperancy by changing brush in paintEvent.
Hope this is the effect you wished.
This is up to the window manager to add such effect.
For example, KWin and Mutter both have their way to handle dialogs. KWin does shade the main window, and I think Mutter does it too with some additional effect.
In Mac OS, modal window are already have special properties to put it in focus on relation of it's patent window.
The way windows handle this is by forcing the focus on the modal I think. But it really is the window manager's job, and up to the user's preference to choose what effect should be active.

Qt: issue with QGraphicscene to show an imge

I am trying to develop very simple image viewer using QT. I am using the following code to show the image on QGraphicsScene widget:
QImage image(fileName);
firstPicture = new QGraphicsScene();
firstPicture->addPixmap(QPixmap::fromImage(image));
ui->graphicsView->setScene(firstPicture);
ui->graphicsView->fitInView(firstPicture->sceneRect() ,Qt::KeepAspectRatio);
I am getting the following output:
How can I fit the image into the GraphicsScene?
This approach works only when view showed your scene. In your case you did not call show(). Solution:
Use your approach when scene already shown.
You can reimplement showEvent and use your approach here.
You can scale image by yourself and set this scaled image to scene.
Also you can try to use: Qt::IgnoreAspectRatio instead of Qt::KeepAspectRatio.
You can make your custom class which inherits from QGraphicsView. You should reimplement resizeEvent( QResizeEvent *event ) in your custom QGraphicsView like:
void MyView::resizeEvent(QResizeEvent *event)
{
fitInView(firstPicture->sceneRect(), Qt::KeepAspectRatio);
QGraphicsView::resizeEvent(event);
}
This way the view will always display the whole scene. I.e. if the window size is changed and the graphicsView is resized, The scene gets scaled and you can see everything appropriately.

Display QImage within main window

I'm trying to display an image with Qt, I can get it to appear in a separate window, but I can't make it appear within the main window
Qt_first w;
w.show();
This shows the window I designed in Qt designer, how do I access the Qlabel(Image_Lbel) I put within the QWidget (centralWidget) of that window?
I generated a stripy image that shows correctly, just not within the correct window
QSize size = QSize(640,480);
QImage::Format format = QImage::Format_ARGB32;
QImage image = QImage::QImage(size, format);
//generate
QLabel myLabel;
myLabel.setPixmap(QPixmap::fromImage(image));
myLabel.show();
I get the feeling it could be I haven't included the files from the creator or the namespaces any suggestion much appreciated
I guess your Label is getting displayed independently. Set the parent of label to your main window. Then your Label will displayed inside your main window.
So use,
QLabel *myLabel = new QLabel(this); // sets parent of label to main window
myLabel->setPixmap(QPixmap::fromImage(image));
myLabel->show();
You can also use move function for moving your label within the main window.
If you want to set the label from outside the Qt_first class, you need to add a method to do this. For example (in qt_first.cpp, change qt_first.h accordingly):
void Qt_first::setImageLabel(const QImage& image)
{
ui->Image_Lble.setPixmap(QPixmap::fromImage(image));
}
ui in this example is the object that represents the UI that you created with Qt Designer.
I used a combination of both answers, thanks to both
Qt_first w; // the UI I made with Qt creator
QLabel *myLabel = w.getImageLabel();
myLabel->setPixmap(QPixmap::fromImage(image));
w.show();
With the following inside the Qt_first class
QLabel* Qt_first::getImageLabel(){
QLabel *myLabel = ui.Image_Label;
return myLabel;
}

QGLWidget + QGraphicsScene + QGraphicsView problem

I would like to create a simple thumbnail viewer using QGLWidget, QGraphicsScene and QGraphicsView. And I have a problem with placing QGLWidget on QGraphicsScene. The code is similar to this:
QGraphicsScene *testScene = new QGraphicsScene (0, 0, 400, 400, 0);
QGLWidget *testWidget1 = new QGLWidget();
testWidget1->renderText("Test text1");
QGLWidget *testWidget2 = new QGLWidget();
testWidget2->renderText("Test text2");
testScene->addWidget(testWidget1);
testScene->addWidget(testWidget2);
QGraphicsView *testView = new QGraphicsView();
testView->setScene(testScene);
testView->show()
It is possible to place few QGLWidgets on QGraphicsScene/QGraphicsView? Where I doing something wrong? Is there any other component on which I could embed QGLWidgets and show them on the screen?
Thanks for help
To make QGLWidget show in QGraphicsView, you should redirect painting for it. You can overwrite the paintGL like this:
virtual void MyGLWidget::paintGL()
{
QGLWidget::paintGL();
//support redirecting painting
QPaintDevice* device = QPainter::redirected(this);
if (device != NULL && device != this)
{
QImage image = grabFrameBuffer();
QPainter painter(this);
painter.drawImage(QPointF(0.0,0.0),image);
}
}
It works well for most platforms, but still happens to show black widget.
The QGraphicsScene::addWidget documentation states that QGLWidget is not a supported widget type.
Parenting a QGLWidget onto the viewport of the QGraphicsView doesn't seem to work either.
Edit:
Actually parenting a QGLWidget to the viewport does work provided I put the renderText call within the paintGL method of my test GL widget.
From the QGraphicsView docs:
To render using OpenGL, simply call setViewport(new QGLWidget). QGraphicsView takes ownership of the viewport widget.
So, in order to draw text on the view, use a QGraphicsTextItem rather than trying to draw text using the QGLWidget.