Drawing Frames arround Widgets
-
Ok this is maybe a weired question.
I try to make a minesweeper clone in Qt. I already have all the elmenets like the LCDs, the face and the Minefield. However I wonder how you could draw the frames arround them. Maybe you can give me some hint how to do it the easiest.
-
Hi
Since you cannot draw outside a
Widget form its paintEvent
its not that trivial to do.I used an overlay widget ( transparent for mouseclicks) to draw
around widgets.
https://stackoverflow.com/questions/19199863/draw-rectangular-overlay-on-qwidget-at-clickCan I ask what the use case is?
Maybe there is easier way to fulfill the same requirement. -
Like i said i would like to draw the frame arround the widgets like the classic minesweeper has:
I have the 2 LCD Displays the SmilieyButton and the minefield as Widgets. So i wonder how i can archieve to have the frame arround them.
-
@sandro4912
Hi
Well the easy way would be to put them/each
inside a QFrame and style that one to look like you want. -
Ok this kinda works. I used 3 Frames like this:
However to archieve the style like above i need to switch white and black lines from the borders of the inner ones. Is there a way to do that?
-
-
With the frames my App looks like this:
How can i get rid of the spacings from the frame to the widgets?
I thought it was in the layout and
setSpacing(0);
whould remove it but it doesn'tThe code so far:
private: LcdDisplay *mLcdDisplayMinesLeft; LcdDisplay *mLcdDisplayElapsedTime; SmileyPushButton *mSmileyPushButton; Minefield *mMinefield; QFrame *mTopFrame; QFrame *mBottomFrame; QFrame *mMainFrame;
Game::Game(QWidget *parent) : QWidget(parent), mLcdDisplayMinesLeft{ new LcdDisplay{ mDefaultMines} }, mLcdDisplayElapsedTime{ new LcdDisplay }, mSmileyPushButton{ new SmileyPushButton }, mMinefield{ new Minefield{ mDefaultFieldWidth, mDefaultFieldHeight, mDefaultMines }}, mTopFrame{ new QFrame }, mBottomFrame{ new QFrame }, mMainFrame{ new QFrame } { mMainFrame->setFrameStyle(QFrame::Panel | QFrame::Raised); mMainFrame->setLineWidth(3); mTopFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken); mTopFrame->setLineWidth(3); mBottomFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken); mBottomFrame->setLineWidth(3); auto topLayout = new QHBoxLayout; topLayout->setSpacing(0); topLayout->addWidget(mLcdDisplayMinesLeft); topLayout->addStretch(); topLayout->addWidget(mSmileyPushButton); topLayout->addStretch(); topLayout->addWidget(mLcdDisplayElapsedTime); mTopFrame->setLayout(topLayout); auto bottomLayout = new QHBoxLayout; bottomLayout->setSpacing(0); bottomLayout->addWidget(mMinefield); mBottomFrame->setLayout(bottomLayout); auto mainLayout = new QVBoxLayout; mainLayout->setSpacing(0); mainLayout->addWidget(mTopFrame); mainLayout->addWidget(mBottomFrame); mMainFrame->setLayout(mainLayout); auto layout = new QVBoxLayout; layout->setSpacing(0); layout->addWidget(mMainFrame); setLayout(layout); }
-
@sandro4912
Hi
Looking good. :)The space can most likely be removed with
layout->setContentsMargins(0,0,0,0);
all layout have a default values of 9 for all 4 sides
-
Appling the margin i get this:
This is almost perfect. Just one nitpick.
The Top and Bottom frame seem to touch each other without any spae inbetween. Any change to add a space like between the outside frame and the inside frames?
The code now looks like this:
auto topLayout = new QHBoxLayout; topLayout->setSpacing(0); topLayout->setContentsMargins(0,0,0,0); topLayout->addWidget(mLcdDisplayMinesLeft); topLayout->addWidget(mSmileyPushButton); topLayout->addWidget(mLcdDisplayElapsedTime); mTopFrame->setLayout(topLayout); auto bottomLayout = new QHBoxLayout; bottomLayout->setSpacing(0); bottomLayout->setContentsMargins(0,0,0,0); bottomLayout->addWidget(mMinefield); mBottomFrame->setLayout(bottomLayout); auto mainLayout = new QVBoxLayout; mainLayout->setSpacing(0); mainLayout->addWidget(mTopFrame); mainLayout->addWidget(mBottomFrame); mMainFrame->setLayout(mainLayout); auto layout = new QVBoxLayout; layout->setSpacing(0); layout->setContentsMargins(0,0,0,0); layout->addWidget(mMainFrame); setLayout(layout);
-
I could solve the Issue by removing the Space 0 here:
auto mainLayout = new QVBoxLayout; //mainLayout->setSpacing(0); mainLayout->addWidget(mTopFrame); mainLayout->addWidget(mBottomFrame);
Which gives:
That looks pretty close to the original:
Although it looks like there is still some kind of space between the minefield and the frame? Can it be removed aswell?
-
Hi
It looks very much like the original
How nostalgic :) -
Yes the only Issue I still see is the remainig space between minefield and the bottomFrame.
-
Hi
There ?
-
Yes in the original theres no space at all.
I already throw out the top frame for testing to see if it causes it but still same result.
-
@sandro4912
Hi
Im not sure where that space comes from as it seems you have it to zeroauto bottomLayout = new QHBoxLayout;
bottomLayout->setSpacing(0);
bottomLayout->setContentsMargins(0,0,0,0);
bottomLayout->addWidget(mMinefield);
mBottomFrame->setLayout(bottomLayout);Did you try to raise the margins to see if you then get more space there ?
-
This post is deleted!
-
hi @sandro4912 ,
my guess is, that the margins come from the mainLayout. You only set the
setContentsMargins
to 0 inside the bottomLayout, but the insert that layout into the mainLayout which has its own contentMargins still != 0 -
No it still has the same Issue:
auto topLayout = new QHBoxLayout; topLayout->setSpacing(0); topLayout->setContentsMargins(0,0,0,0); topLayout->addWidget(mLcdDisplayMinesLeft); topLayout->addWidget(mSmileyPushButton); topLayout->addWidget(mLcdDisplayElapsedTime); mTopFrame->setLayout(topLayout); auto bottomLayout = new QHBoxLayout; bottomLayout->setSpacing(0); bottomLayout->setContentsMargins(0,0,0,0); bottomLayout->addWidget(mMinefield); mBottomFrame->setLayout(bottomLayout); auto mainLayout = new QVBoxLayout; mainLayout->setSpacing(0); mainLayout->setContentsMargins(0,0,0,0); mainLayout->addWidget(mTopFrame); mainLayout->addWidget(mBottomFrame); mMainFrame->setLayout(mainLayout); auto layout = new QVBoxLayout; layout->setSpacing(0); layout->setContentsMargins(0,0,0,0); layout->addWidget(mMainFrame); setLayout(layout);
Result: