I need to show shadow around my mainWindow, and I cannot set my mainWindow WA_TranslucentBackground as I need to show video,any ideas to set the QMainWindow shadow without transparent?
You need to
Create top level QWidget
Make it translucent and frameless
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
Insert your MainWindow into created widget. Left some margins for shadow (about 5-15 px)
Add QGraphicsDropShadowEffect to MainWindow:
QGraphicsDropShadowEffect *wndShadow = new QGraphicsDropShadowEffect;
wndShadow->setBlurRadius(9.0);
wndShadow->setColor(QColor(0, 0, 0, 160));
wndShadow->setOffset(4.0);
mainWindow->setGraphicsEffect(wndShadow);
Look like:
Related
I have a main QWindow and a QFrame (mainF) on it, which contains some other gui elements. I maximize the QFrame as follows, if I click on a button on my QWindow:
mainF->setWindowFlags(Qt::Dialog);
mainF->setWindowState((mainF->windowState(), Qt::WindowFullScreen));
mainF->show();
To minimize the QFrame and place it in its previous position again, I have created a QDialog (m_MinimizeFullscreenGui) with a button on it, which appears immediately on the right top corner of my QFrame if I maximize it:
QRect windowRectangle= m_MinimizeFullscreenGui->geometry();
WindowRectangle.moveTopRight(QApplication::desktop()->availableGeometry().topRight());
m_MinimizeFullscreenGui->setGeometry(windowRectangle);
m_MinimizeFullscreenGui->setFixedSize(30, 30);
m_MinimizeFullscreenGui->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
m_MinimizeFullscreenGui->setWindowState(m_MinimizeFullscreenGui->windowState());
m_MinimizeFullscreenGui->show();
The problem is: I want to have my small dialog window always on the top-level of my maximized QFrame. But if I click at somewhere on my QFrame, the dialog window goes in the background, so the Qt::WindowStaysOnTopHint flag doesn't work.
Where can be my mistake?
I have just started using Qt (5.3) and encountered the fact that some controls appears with margins which I cannot control.
First, I tried to put QLabel and QPushButton right inside QMainWindow
window = new QMainWindow;
label = new QLabel( title, window );
In this case label appears with a margin of 12 pixels at the top (see picture).
QPushButton appears with 1 pixel top & left margins.
But if I insert QFrame with a border, it appears without any margin.
So the margins seem to be attributes of QLabel and QPushButton.
BUT:
When I tried to add extra QFrame between windows and controls:
window = new QMainWindow;
frame = new QFrame(window );
label = new QLabel( title, frame);
I had got different picture:
QLabels top margin had shortened to 1 pixel
QPushButton 1 pixel margins remained intact, but the height of the button had changed
I have tried:
setStyleSheet( "padding:0px" )
and
setContentsMargins( 0, 0, 0, 0 )
for all elements, but without any success.
Any help would be greatly appreciated
The QMainWindow class isn't designed to have widgets added to it directly. Whatever results you see are due to this fact.
The "margins" that you see are not really margins. Since a QLabel is a QFrame, you can enable its frame to see that it has no margin - merely the text is offset from the edge, and that's by design. You can similarly overlay a same-size translucent rectangle on a QPushButton to see that there is also no margin, merely the styling adds its own platform-specific margin. Do not mistake the platform styling mechanism for the style sheets: they are two separate mechanisms and mostly exclusive, with the use of the latter disabling the effects of the former, with few exceptions. For example, the stylesheet spacing/margins/padding is additive to whatever the platform style mandates.
See this answer for an example of how to show overlays on any widget without subclassing.
In Qt5, I have a QDialog window on which I have drawn a circle as follows:
void MyDialog::paintEvent(QPaintEvent *pe)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);
QPen pen(Qt::blue,2);
painter.setPen(pen);
QRect r=QRect(0,0,100,100);
painter.drawEllipse(r);
}
If I draw a larger circle, for example by using QRect(0,0,500,500);, the circle being greater than the dialog window is clipped. So I dragged a QScrollArea onto the the dialog window and decide to draw onto that so that scroll bars are automatically added. The QScrollArea can be accessed using ui->scrollArea.
I changed the above code by setting QPainter painter(ui->scrollArea);. However, nothings appears in the QScrollArea. I read that I need to override the paintEvent of QScrollArea. But I don't know how to do this.
Any help of drawing on the QScrollArea?
Drawing on the QScrollArea is not what you want either because the QScrollArea actually has a viewport widget.
Create another class which inherits QWidget. Override the paintEvent() method and to the painting you mention. Then, add the widget to the scroll area in your dialog.
MyDialog::MyDialog()
{
QScrollArea *pScrl = new QScrollArea(this);
pScrl->setWidget(new MyWidget(pScrl));
... // use a layout to put the scroll area in the dialog
}
To really make it useful you will need to resize the MyWidget instance to the size of the circle that you want to draw.
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.
I have a QGridLayout filled with my custom QWidgets (I'll call them CellWidgets). I want to display a grid between all of the CellWidgets so the columns and rows are clearly visible.
Obviously this isn't done from QGridLayout, as that is simply a holder for widgets that draw themseleves. I made my CellWidgets draw a border by over-riding the paintEvent function like so:
QPainter Painter(this);
Painter.setPen(QPen(QBrush(Qt::white), 2));
Painter.setBrush(Qt::black);
Painter.drawRect(0, 0, width(), height());
The QGridLayout spacing is set to 0, however, when it is drawn the grid border has a single width around the edges and double that width between cells, as the border of the cell is effectively being displayed twice.
Any clean way to solve/avoid this problem?
I think you are heading in the wrong direction.
Instead of painting your widget you should try to change the background color of parent widget to get the effect that you want.
Check out this link for an example.
I hope this helps.