IVideoWindow update problem - c++

I want to render the video from my webcam into QWidget. I've set QWidget, as a parent to IVideoWindow. Here is the code:
m_iVideoWindow->put_Owner((OAHWND)widget_->winId());
m_iVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
m_iVideoWindow->put_Left(0);
m_iVideoWindow->put_Top(0);
widget_->setChild(m_iVideoWindow);
Also i've reimplemented QWidget's resize event, and so when it's resizing it also resizes the IVideoWindow. Everything works good, when the widget is not set to the QLayout. When is - it becomes blank. That is the problem.

I think when Qt draws its widgets, it doesn't redraw them unless it knows they need to be updated. I'm also unsure as to whether it passes on whatever redraw stuff windows requires, to the window you've assigned as a child of the widget.
When I embed my own windows in a Qt widget, I use http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Windows/qtwinmigrate/, but that may not solve your problem, as I still have to use a QTimer to force an update of my window.

Related

Drawing outside of the QPaintEvent handler

We have big QT project where painting procedure often doesn't follow the rule that it should be done in overridden paintEvent method. As result we have warnings about it: Painter not active etc... But all work fine and at first glance I don't see any problems. Could you explain should I worry about it or not? What is the price of the incorrect use of this functionality?
Paint event is sended to the window when it is should be updated, eg when it is shown or something else. For example if widget is covered by another window, and this windows is moved away, then widget should be updated. Common way is to paint on the pixmap and draw this pixmap on the widget in the paint event handler. Or you can update/repaint each time you need to repaint it.
You can use QPainter to draw on pixmap, printer and so on whenever you want, but to draw on windget it must be done in paintEvent.
I found mistake - it is happened when invalid pixmap(I have created pixmap with size 0x0) is used. I have add check on it and now all are okey.

Qt graphic obscured by another, but still causes paint update

I'm using Qt5.6, I have QWidget graphic objects rendered and when other graphics are rendered in front of others this seems to trigger updates of the graphics under the graphics in front.
This creates overhead, I would like to determine if the graphic behind is completely obscured by the graphic in front and if so, then it should abort the paint event.
I thought this would be automatic and done as part of the internals of Qt, but it seems not.
Each widget's paint event is comes from the widget compositor, once the compositor determines that a widget should be repainted. There's no way to abort it: if the event arrives, it means that the widget must paint, or else you'll get visually undefined results.
By default, widgets can be transparent, and the widget compositor has to paint the entire stack of widgets in back-to-front order to compose them.
Any widget that is not transparent should have the Qt::WA_OpaquePaintEvent attribute set. This will inform the widget compositor that any widgets completely hidden behind the widget don't have to be painted. Ensure that you paint every pixel of your widget!

Qt - Make QMainWindow to non resizible in Qt Designer

Is it there a way to set a QMainWindow to be non-resizible in Qt Designer? I am seeing lots of coding examples but I want to do as much UI customization in Qt Designer as I can. So far I can only get this by setting the minimum size and maximum size to be equal, but still there is the resize arrow in the corner of the window and a "maximize" button on the top of the window.
When you select the QMainWindow, the properties of the object does contain a field for sizePolicy, both horizontal and vertical, as mentioned by the answer of #jester and you can set those to fixed.
I have found that doesn't always work and was never sure why (perhaps to due to layouts), but as you've found out, if you set the minimumSize and maximumSize fields to the same value, it does what you want.
As for the resize arrow and maximize button, I have never been able to do that from Qt Creator (designer), so I would say it's not possible. However, just one line of code is all you should need in the constructor of your class: -
setWindowFlags(Qt::Window | Qt::CustomizeWindowHint);
By default, the window flags include Qt::WindowMaximizeButtonHint. By setting the above flags, you're stating that you want to customise the window to include the specified elements. This will also remove the minimise button, so if you want that too, you should add Qt::WindowMinimizeButtonHint
I am not using Qt Designer; I am just writing a subclass of QMainWindow made from scratch. The solution I found for having a non-resizable window is to call setFixedSize on the QMainWindow after you have set up all your widgets and layouts. If you have set things up well, then you don't have to pick a size manually; you can just get the size from sizeHint. The line of code I used inside my subclass of QMainWindow is:
setFixedSize(sizeHint());
I tested this in Qt 5.5 on Windows 8.1 and everything looks fine: the maximize button gets disabled but the other buttons are still there, and the cursor does not indicate the possibility of resizing when the user moves it to the border.
use the setFixedSize property for the QMainWindow. In designer, if I remember correctly, you can set the horizontal and vertical sizePolicy to Fixed.
Sadly there is no option to do that; in VS you may find an option in the editor, to remove the mouse trigger that resize the window; but for some reason, QT5 does not have one.
I tried to use sizePolicy and set it as fixed for mainWindow; but this does nothing for both the horizontal and vertical policy.
To solve the problem, I did set my mainwindow minimum and maximum size as the same values; and when you run the application, the mouse cursor won't be enabled for resizing.
It is an ugly way to do something so simple, but this is the only way I found in QT designer, without use code.
I solved the problem of Qt5 which is displaying mouse arrow resize window even with window having fixed size, but in Python, but you can make modifications for C++.
MainWindow.setWindowFlags(QtCore.Qt.MSWindowsFixedSizeDialogHint)
It's an old post but I want to help if someone need it.
I found a way (not so beautiful) but it works directly from QTDesigner.
You can lock the resize by writing the values of height and width also inside "MinimumSize" and "MaximumSize" property.
Oviously also set "Fixed" on vertical and horizontal as told by other users.
This will remove the button to enlarge the window.

How does a Qt custom widget notify ScrollArea parent about change of view

I'm writing an image viewer as a custom Qt widget (see: https://github.com/dov/Qviv) and I now got stuck on the question of how to make my widget notify a parent QScrollArea of changes in the view port, and thus to tell it to move the scrollbars. E.g. if the image viewer changes the zoom factor as the result of a keypress then the scrollbars need to change their page size.
One way of doing it would be to have the widget explicitly check if the parent is a QScrollArea and then make an explicit call to its methods to notify it on any changes.
Of course I also need to connect the changes of the ScrollArea to the internal view of the image, but that is a different question. And I need to cut the infinite recursion where the widget reports changes to the scrollbar that report changes to the widget etc.
Edit 20:15 Wednesday (GMT/UTC) trying to clarify to Vjo and myself what I need.
What I am trying to achieve is the equivalent of a Gtk widget that has been assigned a pair of GtkAdjustment's that are connected to a horizontal and vertical scrollbar. In my widget GtkImageViewer, that QvivImageViewer is based on, whenever I change the view due to some internal event (e.g. a keypress) I update the GtkAdjustment's. The scrollbars are connected to such changes and are update accordingly. GtkImageViewer also listens to the GtkAdjustment changes, and thus if the user scrolls the scrollbars, the GtkImageViewer is updated with this information and can change its view. My question is whether there is anything similar to GtkAdjustment in Qt that you can connect to for changes, and update in which case the update will be propagated to all the listeners?
Thus I don't expect the ScrollArea to be part of QvivImageViewer, but if the user has placed QvivImageViewer within a ScrollArea, I want bidirectional communication with it so that the scrollbars reflect the internal state of the widget.
The simplest is to send the QResizeEvent event from your widget object to the QScrollArea object.
I finally downloaded the Qt sources and investigated how QTextEdit does it. What I found is that QTextEdit inherits the QAbstractScrollArea on its own, and thus the scroll area and the scrollbars are part of the widget. This is different from Gtk, which uses a higher level of abstraction, through its GtkAdjustment's that are used to signal changes between the scrollbars and the widget. The Qt model is simpler and this is the way that I will implement it in my widget.
It's been a while, but I ran across this same issue.
You can inherit QAbstractScrollArea if you'd like, but QScrollArea will work as well.
Your custom inner widget (i.e. the one that you are scrolling), should do the following when its size changes:
void MyCustomControl::resize_me() {
// recompute internal data such that sizeHint() returns the new size
...
updateGeometry();
adjustSize();
}
QSize MyCustomControl::sizeHint() {
return ... ; // Return my internally computed size.
}
I was missing the adjustSize() call, and without it the QScrollArea will ignore size changes of the internal widget.

mouse over transparency in Qt

I am trying to create an app in Qt/C++ with Qt4.5 and want the any active windows to change opacity on a mouseover event...
As i understand it, there is no explicit mouseover event in Qt.
However, I got rudimentary functioning by reimplementing QWidget's mousemoveevent() in the class that declares my mainwindow. But the mainwindow's mousemoveevent is not called whenever the mouse travels over any of the group boxes i have created in there (understandbly since QGroupbox has its own reimplementation of mousemoveevent).
So as a cheap work around, I am still using the mousemoveevent of my mainwindow but a query the global mouse position and based on the (x,y) position of the mainwindow (obtained through ->pos()) and the window size (-> size -> rHeight and rWidth), I check if the mouse is within the bounds of the area of the mainwindow and change the opacity thus.
This has had very limited success. The right border works fine, the the left changes opacity 4 pixels early. The top does not work (presumably because the mouse goes through the menubar and title bar) and the bottom changes way too early.
I thought of creating an empty container QWidget class and then place all the rest in there, but i felt that it would still not solve the big issue of the base widget not receiving the mousemoveevent if it has already been implemented in a child widget.
Please suggest any corrections/errors I have made in my method or any alternate methods to achieve this.
p.s. I doubt this matters, but I am working Qt Creator IDE, not Qt integration into VS2008 (it's the same classes anyways - different compiler though, mingw)
Installing event filters for each of your child widgets might do the trick. This will allow your main window to receive child events such as the ones from you group boxes. You can find example code here.
You may be interested in Event filters. QObject proves a way to intercept all events zipping around your application.
http://doc.trolltech.com/4.5/eventsandfilters.html#event-filters
If I understand what you are attempting to do, I would reimplement the widget's enterEvent() and leaveEvent(). The mouse enter event would trigger the fade-in and the leaveEvent would trigger the fade-out.
EDIT: After re-reading several times, I'm still not sure what you are trying to accomplish. Sorry if my suggestion doesn't help. :-)