Screenshot in a small part of Qt-Window - qt

I would like to be able to take screenshots of my program and save them as png (or if it is possible as pdf). I have taken the screenshot-example from Qt. This takes a screenshot from the whole display. But I would like to take a screenshot from only a part of my window, even if it is in another postion of the display. How can I do that. Is there a function?

The static function grabWidget of QPixmap is your friend. You can easily take a pixmap of the provided widget and then save it in any format you desire:
QPixmap p = QPixmap::grabWidget(widget);
p.save("p.png");

What about QWidget::render (http://doc.qt.nokia.com/4.7-snapshot/qwidget.html#render)?

Examine the window to get it's position and size. If you have any specific element you want to see in the screenshot, you can get it's position and size instead. Otherwise, you'll have to use offsets from the window position which can cause trouble (for example, when the window is resized).
Get the screenshot and then crep the pixmap using the position/size from before.
There is one drawback: Taking a snapshot of the whole desktop is somewhat slow.
So a better solution might be to change your application: Render the parts you want to save in an off-screen buffer. You can then use this buffer to render the UI and save the screenshot at the same time.

Related

Generate thumbnail from stage for react-konva

I have created a react app Which is very similar to office whiteboard. I would like to generate a thumbnail or card preview of each whiteboard and wondering how to go about it.
My initial thought was to just create a card component and render the shapes to that the same way I do for the real whiteboard. However, the points for each shape will be outside the stage and I can't think of how I can scale it down.
Any ideas?
Take a look at the official canvas thumbnail demo from Konva.
You can use a similar approach with react-konva.
Create a special component for the preview.
I think this approach will work better and probably more performant (depending on your app). You just need to create another Stage and draw all objects into it. It will be better if you can draw simplified versions of the shape, because the drawing is much smaller, so not all details are visible.
You will have to calculate your own scale ratio.
Use image preview
Instead of making a full components tree for the whiteboard, you can just export the main stage into an image and show it. You have to do reexport from time to time.

Persistent window size for floating windows in awesomewm

I resize a floating window, let's say to some size WxH pixels. Then I change to tiling mode, so the window gets resized automatically to some new size, let's say W'xH' pixels. Now suppose I switch the window back to floating mode.
What I Want: The window automatically resizes to the last size, i.e., WxH.
Current Situation: The window just becomes floating, but still has the size W'xH'.
Is there any way of making this happen? Like some way we can save the dimenisons of a window everytime it's resized, and whenever a window enters floating mode, apply the last known size from that application?
I know it probably sounds very dumb, I'm so sorry.
There is multiple ways. The "simple" way is to use client.connect("property::floating", function(c) if c.floating then restore(c) else save(c) end) where you implement both save and restore yourself by calling c:geometry().
The more advanced way would be to use request::geometry and awful.placement built-in geometry memento support. That's preferred since it allows to prevent the client from flickering between 2 sizes. However it is much more complicated to pull off.
You can use awesome-remember-geometry from berlam.
https://github.com/berlam/awesome-remember-geometry

QQuickwidget grab image outside window area

This is a sequel to another question here in which I was not precise while describing my goal.
As mentioned in the linked question, I wish to save a QML which is embedded in a QQuickWidget and it is larger than the window size. The QQuickWindow grabWindow() method captures only the window area and hence I tried the following code after I visually displayed it:
QQuickWidget* content..
content->setSource(QUrl("qml:/main.qml"));
QPixmap *pm = content->grab(QRect(QPoint(0,0),QSize(-1,-1));
pm->save("someFilename.png", 0, 100);
So, it is definitely not the issue of saving image after rendering. The used QML code is just a plain Rectangle. The proposed solutions in the previous question only grabs content falling within the window.
Any suggestions? Thanks! :)
Addendum:
I have tried the following but didn't work:
QImage paintdev(largeWidth, largeHeight, QImage:Format_RBG32);
content->render(paintdev, QPoint(0,0), QRegion(QRect(0,0,largeWidth, largeHeight), QWidget::DrawChildren);
paintdev.save(fileName, 0, 100);
This should by logic solve the issue of window size since there is no window. Any comments?
Ok, so I solved it by manually shifting the QML by the window height and saving all the images from the window captures and collate it to form the original image.
Not too much work though, but I am still mystified by the QWidget render() method which did not work.
Thanks for all the replies!
If your QML content is larger than the window size, the part that is out of screen is not drawn. Hence, there is no way to capture something out of screen, unless you use 2 monitors and extend view. This last approach would work.

QTableView Zoom In/Out

I'm trying to create a QTableView that can be zoomed in and out like in Excel.
A similar question was asked here: Zooming function on a QWidget
However, I'm subclassing the QTableView in PyQt and not C so reimplementing the entire PaintEvent method is a bit evolved. The source code for that is a bit complex: https://qt.gitorious.org/qt/tiittane-qt/source/bdd4a9149789f60974603e1f7621d51378f0a108:src/gui/itemviews/qtableview.cpp#L1282
I'm looking to see if there are any other viable options to have a zoom able TableView. My first attempt was by setting the font size then realized each column and row widths would have to scale as well which can become slow. Then realized changing the font would change the print. It didn't seems like an elegant solution. Changing the scale of the painter before painting seems like the more elegant solution but would have to re-implement and translate quite a bit of code to python to do so. I'm wondering if there are any other hooks to get this done.
Thanks
If you can use QTableWidget instead then you can create a QGraphicsScene and add it to that. Then you easily control the scale of the widget within.
If you want vertical and horizontal headers always visible I think you will have to turn off the table's scrollbars (which would end up zoomed, probably not what you want anyways) and have the scrollbars part of the panel that contains the graphics scene (probably panel would be a QAbstractScrollArea with 4 cells in layout: one cell for scene, one for horiz scrollbar, one for vert scrollbar, and one for the corner maybe empty), and connect them to the table's scroll behavior.
There is no built-in method to zoom on a view.
The simplest way to separate the size of the font on the screen, versus the size of the font saved or printed, is to basically have two fonts. One to be displayed on the screen you can call 'zoom', versus the other to be saved/printed and call that 'font size'.
Note this answer is cut and pasted from the same question:
Zooming a view in PyQt?

qt: after moving window off-screen, how to move it back to default position, including default positioning behaviour?

[qt 4.8]
To get correct window dimensions including its frame, I do the following (as described e.g. here, see comment from Daniel Hedberg).
mainWindow.move(-50000, -50000);
mainWindow.show();
// do something with the window dimensions
mainWindow.move(0, 0);
mainWindow.show()
This works fine, however, I have a problem with the move(0,0) call: It makes the window always appear at position (0,0), while I would like to have the default behaviour, this is, the application only suggests to the window manager that (0,0) is a good place to position the window, and the WM might decide to shift it if necessary to avoid overlapping. In other words, I would like to switch back to Qt's default behaviour as if there weren't a call to move at all.
How can I do that?
One solution is to store Windows original position and use that. For extra safety (in case screen resolution changes), check that entire window still fits on screen and move and even resize if it does not.
A hacky alternative would be to create and open empty, possibly transparent dummy window of the same size and see where it gets positioned. Then move the original there and close the dummy one. Reading your question carefully, I think this would do what you are after.
I don't know of a Qt way to ask Window Manager to reposition the window, so if you really need that, specify the OS etc details.
Looking into the source code of Qt, I can now partially answer my own question: To convert a call to move into a suggestion for positioning instead of a request, do this:
mainWindow.move(100, 100);
mainWindow.setAttribute(Qt::WA_Moved, false);
mainWindow.show();
I've tested the code under X11 using Qt 4.8.4, and hopefully it works with on other platforms too.
Unfortunately, this doesn't solve the very problem I have, namely to use show to get the (decorated) dimensions of an off-screen window which then gets moved to the screen, calling show again. It seems that the first call to show directly sets platform-specific window manager flags which aren't completely reset and reevaluated in the second call. Actually, I'm going to think that this is a bug in Qt, so I'll report it accordingly.

Resources