How to make a free space around a Frameless QWidget? - qt

I have made a custom Window in Qt and now facing to resizing problem.
I want a free space around my QWidget (Qt::FramelessWindowHint) so i can process the Mouse Hover+Leave+press+release events in that area and in this events i change the cursor shape and resizing the widget.
(I don't want mouseEvent for widget but for that space)
How could i get such area ?

I suppose your QWidget is added to a QLayout at some point. Then just ask the containing QLayout to reserve some free space around it's content by calling [setContentsMargins].
Example, you had:
QWidget* widget = new QWidget( parent );
parent->layout()->addWidget( widget );
Then, just add:
parent->layout()->setContentsMargins( 100,100,100,100 );
This will guarantee that widget has 100 pixels of empty area around it.
To be more generic, and it case you had no parent, you can create an intermediate QWidget like that:
You had:
QWidget* myWidget = new QWidget( NULL );
widget->show();
Just do:
QWidget* parentWithEmptySpaceBorder = new QWidget( NULL );
parentWithEmptySpaceBorder->setLayout( new QVBoxLayout() );
parentWithEmptySpaceBorder->layout()->setContentsMargins( 100,100,100,100 );
QWidget* myWidget = new QWidget( NULL );
parentWithEmptySpaceBorder->layout()->addWidget( myWidget );
parentWithEmptySpaceBorder->show();

Related

How to autofit widget size and position to a cell in QTreeWidget?

I pragrammaticaly create a QTreeWidget.
Then I pragrammaticaly add some items.
Then I add two QLabel widgets to two items (QTreeWidgetItem) by
myTree->setItemWidget(item1, 0, myLabel1);
myTree->setItemWidget(item2, 0, myLabel2);
And then I try to resize the row of the item pragrammaticaly.
If I use an
item1->setSizeHint(0, QSize(myWidth, myHeight) );
the row chaged. But myLabel1 is not.
If I use an
item1->setSizeHint(0, QSize(myWidth, myHeight) );
myLabel->resize(myWidth, myHeight);
everething is ok but the row of myLabel2 mis adjusting to label by position.
Can I do something to auto-adjusting a widget (by size and position) to a cell of QTreeWidget?
P.S. After any resizing of tree (resize by width or expand/collapse node) widgets updates correctly.
In view of the fact that autofit start after resizing QTreeWidget, there is some method inside that resize widgets in cells.
So I opened QTreeWidget description (https://doc.qt.io/qt-5/qtreewidget.html) and red all of Public Functions and Public Slots. When I did not find any useful function I looked at a parent class (QTreeView). And found
myTree->resizeColumnToContent(0);
Call resizeColumnToContent after resizing any row in a QTreeWidget and widgets will be always fit to cells.
P.S. I am the OP.
you can try adding/updating a widget as an item, for example:
QWidget* wdg = new QWidget;
QPushButton* btIcon = new QPushButton();
QLabel* lb = new QLabel();
QHBoxLayout* layout = new QHBoxLayout(wdg);
layout->addWidget(btIcon);
layout->addWidget(lb);
layout->setAlignment( Qt::AlignCenter );
wdg->setLayout(layout);
myTree->setItemWidget(item1, 0, wdg);
Or just fill the tree with widgets

QTabWidget does not respect spacing from layout

I have this test case:
// Scroll
QScrollArea *sa = new QScrollArea(ui->centralWidget);
sa->setWidgetResizable( true );
// Layout for widgets
QVBoxLayout *vl_2 = new QVBoxLayout();
vl_2->setSpacing(0);
// Widget to attach the scroll to and the layout
QWidget *widget = new QWidget()
widget->setLayout(vl_2);
sa->setWidget(widget);
// Test widgets
QComboBox *cb_1 = new QComboBox();
QComboBox *cb_2 = new QComboBox();
vl_2->addWidget( cb_1 );
vl_2->addWidget( cb_2 );
And the widgets have 0 space between them.
But if I add them to a QTabWdiget, it all breaks as if QTabWidget does not respect the set setSpacing(0);.
// TabWidget
QTabWidget *run_results = new QTabWidget(ui->centralWidget);
run_results->resize( this->size().width() -20, this->size().height() -80 );
run_results->show();
// Scroll
QScrollArea *sa = new QScrollArea(ui->centralWidget);
sa->setWidgetResizable( true );
// Layout for widgets
QVBoxLayout *vl_2 = new QVBoxLayout();
vl_2->setSpacing(0);
// Widget to attach the scroll to and the layout
QWidget *widget = new QWidget()
widget->setLayout(vl_2);
sa->setWidget(widget);
// Add the scroll to as the TabWidget tab.
run_results->addTab(sa, "test");
// Test widgets
QComboBox *cb_1 = new QComboBox();
QComboBox *cb_2 = new QComboBox();
vl_2->addWidget( cb_1 );
vl_2->addWidget( cb_2 );
Anyone know what I need to do to force QTabWidget to not resize and move my widgets so that they take all the space?
I tried to add Qt::AlignTop to the addWdiget but it did nothing other than place the first widget at the top and the next in the middle of the screen.
I understand where I went wrong.
In the first case I add my scrollarea as a sub-widget to the centralwidget. In the second example I add the scrollarea as the centralwidget which expands it to the whole tabwidget.
I resolved the second case by first adding a holder QWidget as the tabwidget and then adding the scrollarea as a sub-widget to it.

QAxWidget don’t display

I used QWidget show as a dialog. And put QAxWidget as a subwidget.
But if I set the parent widget transparent, the QAxWidget will not display.
QWidget* widget = new QWidget;
widget->setAttribute(Qt::WA_TranslucentBackground);
......;
QAxWidget* axieBrowser= new QAxWidget(widget);
axieBrowser->setControl(QString::fromUtf8("{8856F961-340A-11D0-A96B-00C04FD705A2}"));
axieBrowser->dynamicCall("Navigate(const QString&)", "www.google.com");
I try if you use other widget, that will display, only QAxWidget don’t display! How could I fi
xed that?
#Dariusz Scharsig I use this function to force the QWidget fresh because repaint() is no effect.
void CMyDialog::changeRectToFresh()
{
this->showNorMal();
QRect rect = this->geometry();
this->setGeometry(rect.adjusted(-1,-1,1,1);
//recover
this->setCeometry(rect);
}

I get a rectangle behind a QPushButton

I'm new to QT. I used following code to add a button in to a QGraphicScene
QGraphicsScene* scene = new QGraphicsScene;
QPushButton *btnuser = new QPushButton();
btnuser->resize(32, 32);
btnuser->setGeometry(QRect(QPoint(50, 50),QSize(32, 32)));
btnuser->setText("1");
btnuser->setAccessibleName("1");
connect(btnuser, SIGNAL( clicked() ), this, SLOT( on_btnProcess_clicked() ) );
scene->addWidget(btnuser);
But in the output there is a rectangle behind the button. How can I remove that?
I solved this problem by setting minimum width and height.
QPushButton *btnuser = new QPushButton();
btnuser->setMinimumHeight(20);
btnuser->setMinimumWidth(20);
Then I set the same width and height for the button in setGeometry method
btnuser->setGeometry(QRect(QPoint(pointx,pointy),QSize(20, 20)));

QT: Complex Layout and seamless window background image

With some help from you QT sages, I was able to implement this window, with the desired layout and resizeability behavior. Now I have another interesting problem.
I want my entire window to have a "repeat-xy" seamless pattern. If I apply it to a simple window without layout and internal widgets, it works perfectly. I do however, now have a "tree" of widgets within widgets, and I can't set the stylesheet to draw my seamless background image to each and every one, cause it looks unnatural. The image must be underlying to all the widget topology I have. The problem is, it's invisible when i apply it to the bottom all-window-covering widget because it has widgets on top of it.
Is there a solution? maybe "transparent widgets" that can contain visible widgets?
I made the following using only CSS, there's a QPlainTextEdit, two QPushButton and a QLineEdit. In the image i added a red border to the QPlainTextEdit only so it can be seen, the rules are the following
QWidget#Form{
background-image: url(:/img/elephant_pattern.gif);
}
QPlainTextEdit{
background:transparent;
border:1px solid red;
}
As you can see all i had to was setting background transparent in the widgets i wanted.
Write your own widget that inherits QWidget. Reimplement the paintEvent and leave it empty. The widget itself won't be drawn, but its children will be.
my_widget::my_widget( QWidget* parent ) : QWidget( parent )
{
}
void my_widget::paintEvent( QPaintEvent* p_event )
{
// left empty to let my_widget be invisible
}
test_mw::test_mw( QWidget *parent ) : QMainWindow( parent )
{
test_widget = new my_widget( this );
QHBoxLayout* layout = new QHBoxLayout();
QPushButton* button0 = new QPushButton( "Button 0", 0 );
QPushButton* button1 = new QPushButton( "Button 1", 0 );
layout->addWidget( button0 );
layout->addWidget( widget );
test_widget->setLayout( layout );
setCentralWidget( test_widget );
}
Although the paintEvent of my_widget is empty, both QPushButtons are drawn. :-)
There was a QWidget::setBackgroundOrigin() method in earlier versions of Qt.
It's all done with styles now. See the examples http://doc.qt.nokia.com/latest/widgets-styles.html

Resources