Qt : event invisible widget? - qt

For some reasons, I need to draw a widget onto one another.
The structure is the following (see the image) :
I have an original QTableWigetItem
On the QTableWigetItem, I create a QWidget at the foreground with the same geometry
This QWidget contains a QBoxLayout
This QBoxLayout contains a QPixmap and a QComboBox
I want to do the following things :
The QWidget is just a "container" for my QBoxLayout and I would like to set him completely "invisible" for the user. If the user click or move at the position of the widget, I want the event of the QTableWigetItem in the background to be trigerred. But the problem is that I want the QPixmap and the QComboBox to be at the foreground, visible and "normal". For me it's just a trick to be able to put children widgets in a QTableWidget of a HeaderView.
How to make the QWidget "completely invisible" (from the event/signals point of view) ?
Thank you very much.

Try QWidget::setWindowOpacity(0)

Related

Qt widget displayed over other widgets

I have some information/notification widget that should be displayed when some even occurs. My idea was to have a widget that is hidden in top left corner and would be shown when needed. Problem is that if I just put there simple widget and show it, everything will be moved to the right, what I want is to show that widget on top anything that's in that area (it will hide what's there, but that's ok).
I can't use stacked widget, because information widget is in different dimensions then other widgets there. And if I just create floating widget and move it to that area it wont move if main window is moved.
Is there any way how to do that?
Just create and place the widget on the fly. Avoid using UI to place the widget because then the widget position is managed by the layouts.
EDIT: Remember to create the widget after of the dialog's initialization. If you don't take care about this your widget will be inserted at the bottom.
class Dialog : public QDialog
{
Q_OBJECT
std::unique_ptr<Ui::Dialog> _ui;
QWidget* _widgetOnTheTop;
public:
Dialog(QWidget* parent)
: QDialog(parent), _ui(new Ui::Dialog)
{
_ui->setupUi(this);
_widgetOnTheTop = new QPushButton(this);
_widgetOnTheTop->setGeometry(10,10,100,35);
_widgetOnTheTop->show();
}
};
Look at QDialog create and exec one of them when your error occurs, you can construct them to have the default ok cancel buttons
EDIT: Sorry i mean QMessageBos, see code below
QMessageBox error_message(QMessageBox::Icon::Critical, "Title of the window","Some Text about the error to show the user", QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::Cancel), this);
error_message.exec();

How to prevent QTableWidget from occupying the whole window in a QHBoxLayout?

In my Qt program, I programmatically generate a modal QDialog. I want to show two widgets in this dialog window: A custom widget showing a camera output and a QTableWidget, showing the pixel coordinates of the corners found in the camera image. I generate a QHBoxLayout and add my custom widget and the QTableWidget into it. Then I set this QHBoxLayout as the Layout of the QDialog window. What I want to achieve is to share the available space in the QDialog's window area equally between my custom QWidget and the QTableWidget, horizontally, by using a QHBoxLayout. But I always end up with QTableWidget occupying the whole QDialog area, by overlapping my custom widget. How can I instruct these two widgets to exactly share the QDialog area?? Note that I first add my custom widget and then the QTableWidget into the QHBoxLayout.
Make sure on your custom widget you've specified a minimumSizeHint and a sizeHint, this instructs the QLayout manager that the widget requires a specific space. To have them split equally you'll be best off detecting the size of the QDialog and then specifying the width for both by removing the boundary sizes (spacing between widgets + space to QDialog edge) and dividing it up.

Attach a QLabel in front of QGLWidget

I have a QGLWidget and I like to attach on top of it a QLabel for some measurement visualization (fps, number of object, etc).
I'd like to keep QGLWidget as clean as possible for further re-using and not use QGLWidget::renderText inside of it but use an external debug interface with those measurement.
For now I have:
QVBoxLayout *l = new QVBoxLayout;
this->gl = new MyGLWidget;
l->addWidget(gl);
QLabel *fps = new QLabel;
fps->setText(QString("FPS"));
fps->setStyleSheet("QLabel { background-color : red; color : blue; }");
fps->setParent(gl);
this->setLayout(l);
But nothing appears.. of course if I add the QLabel to the layout with QLayout::addWidget I see it.. but is not what I want..
Some ideas?
Without being assigned to a layout the widget doesn't know, where it should draw, if you don't tell it explicitly. You must call QWidget::setGeometry explicitly to position it.
However placing regular Qt widgets on top of a QGLWidget has some merits. The QGLWidget actually creates a subwindow parented by the top level window. Regular widgets however don't have their own, deidicated subwindows, which means, that from the point of view of the graphics system they're on the same Z stacking level than the top level window itself. And the QGLWidget's actual subwindow has a higher Z stacking level. Parenting a QLabel to the QGLWidget should place it at the right Z stacking level. But then OpenGL drawing operations are different than Qt drawing operations, so your drawing on the QGLWidget may mess up the QLabel.
Simply spoken, there's a reason why QGLWidget has a function "drawText".

QWidget transparent background (but not the children)

I have a QWidget that contains a QPixmap and a QComboxBox in its Layout. I would like to set the background of the widget transparent (but I want to show the QPixmap and the QComboBox normally). How do I do that?
You can use the attribute
widget->setAttribute(Qt::WA_NoSystemBackground);
Qt documentation :
Indicates that the widget has no background, i.e. when the widget
receives paint events, the background is not automatically repainted.
Note: Unlike WA_OpaquePaintEvent, newly exposed areas are never filled
with the background (e.g., after showing a window for the first time
the user can see "through" it until the application processes the
paint events). This flag is set or cleared by the widget's author.
It is all well-explained in QWidget documentation:
http://doc.qt.io/qt-5/qwidget.html#transparency-and-double-buffering

Layering UI elements in Qt Designer

I have a QLabel that I'm constantly setting it's pixmap (video playback). In my application the user needs to be able to draw (boxes) above the video. How can I layer one of the QPaintDevice classes (QWidget, QPixmap, QImage, etc.) directly above and with the same size as the QLabel for painting. This element will need to have a transparent background so shapes drawn on it will appear over the video.
Add the widget you want to draw shapes on as a child widget of the video label. Add a layout first so the child widget will match the size of the parent widget. The code would be something like this:
QHBoxLayout *layout = new QHBoxLayout(videoWidget);
QLabel *overlayWidget = new QLabel();
overlayWidget->setAlignment(Qt::AlignCenter);
overlayWidget->setText("Overlaid Text");
layout->addWidget(overlayWidget);
You should see the text overlaid on the video and it should remain centered over the video widget if it is resized. For your final code, you would use some widget subclass of your own that allowed you to intercept mouse actions and draw rectangles but that's the basic idea.

Resources