qt5 multiline button with multiple style for each line - c++

Can I make button, that have multiple lines, and each line have different style? When I use gtkmm, I can put widgets inside buttons, so I can make vbox with two different style labels and put it into button. But it looks, like I can't insert widgets into buttons in qt. Maybe there another way, to make multiline button with different style for each line?
Sorry for my English!

After all, I found a solution. I cat put layout of widgest just like in gtkmm. I just use method setLayout() of QPushButton. With this method I can put layout of multiple labels inside button.
QLabel* label = new QLabel( this );
QGridLayout* layout = new QGridLayout( this );
QPushButton* button = new QPushButton( this );
layout()->addWidget( label );
button->setLayout( layout );

Related

How to re-enable the background of QGraphicsView's child widgets?

When adding QWidgets such as QGroupBox and QFrame to a layout set on QGraphicsView, those widgets have no background. Various things that seem like they should re-enable it, do not work. (E.g., setAutoFillBackground(true);.)
Is there some way to get the widgets to draw their background again?
QFrame* mycw = new QFrame();
QHBoxLayout* loMain = new QHBoxLayout();
loMain->addWidget( mycw );
pView = new QGraphicsView();
pView->setLayout( loMain );
pView->showFullscreen();
Edit: This may have something to do with opengl or something. I have tried to work around it, by making the two widgets peers - and using the resizeEvent of the parent to arrange them with no layout at all. And it still happens! If it's drawn in-front of the QGraphicsView, it ends up with no background.
I will have to dig deeper. :(
If you want to apply a background color on a widget you can use maybe:
widget->setStyleSheet("background-color: yellow");

QT: How to trigger "bold" upon mousehover of QMenuBar's items

I am using Qt6 to create a cross-platform GUI application. I am playing around with the automatically generated QMenuBar object in Designer Mode. I want to change the QMenuBar items (File, Edit, Help.. ) to bold and red.
I am using the following code in the StyleSheet editor of the MainWindow object:
QMenuBar::item:selected {
font:bold;
color:red;
}
The code works fine for changing the color of the text but it does not set the font to "bold" as I would like. Also, trying to change the font size does not work.
What am I missing?
Thank you in advance!!
QMenubar does not have a font, you need to give the font separately to QAction. I think this will solve the problem
QMenu *fileMenu ;
QAction *newAct = new QAction(tr("&New"), this);
QFont f = newAct->font();
f.setBold(true);
newAct->setFont(f);
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAct);
but if you want an active QAction then you need to
setStyleSheet("QMenu::item:selected {font: bold;}");

In QT "ui->scrollArea->horizontalScrollBar()->setValue(0)" has no effect

So in my UI designer I have a ScrollArea Widget, I then in my MainWindow.cpp, I create a QGraphicScene and a QGraphics View. I create a new widget and give that widget a QVBoxLayout so that it will auto-size(which is correct to my understanding).
I then use ui->scrollArea->setWidget(widget); to make this new widget the child of my scrollView.
All of this seems correct because I have scroll bars that I can navigate my scene with. However; using the line ui->scrollArea->horizontalScrollBar()->setValue(0); still has no effect on the scroll bar values.
scene = new QGraphicsScene();
scene->setSceneRect(0,0,2500,2500);
view = new QGraphicsView(scene);
QWidget *widget = new QWidget;
view->setBackgroundBrush(Qt::white);
QVBoxLayout* bLayout = new QVBoxLayout(widget);
ui->scrollArea->setWidget(widget);
bLayout->addWidget(view);
widget->show();
ui->scrollArea->horizontalScrollBar()->setValue(0);
ui->scrollArea->verticalScrollBar()->setValue(0);
I just had the this problem. Then, after debugging with ui->scrollArea->verticalScrollBar()->value() I realized that the scrolling area has no size before the component is show on the screen, i.e., it does not change the scrolling because it is not visible yet.
This is a sample Python code, but the is the same for C++, except the Language Syntax.
from PyQt5.QtWidgets import QDialog
...
dialog = QDialog()
...
verticalScrollBar = dialog.QPlainTextEdit.verticalScrollBar()
horizontalScrollBar = dialog.QPlainTextEdit.horizontalScrollBar()
# Has no effect, if you print the values, you will see always 0
verticalScrollBar.setValue( horizontalScrollBar.maximum() )
horizontalScrollBar.setValue( horizontalScrollBar.minimum() )
dialog.show()
# Now it has effect
verticalScrollBar.setValue( horizontalScrollBar.maximum() )
horizontalScrollBar.setValue( horizontalScrollBar.minimum() )
Autoscroll PyQT QTextWidget
If you are sure to address the correct scrollbar (as pointed in the comments by thuga), maybe check if your scroll area is modified after that init. I mean I'm not sure of the bahaviour, but if you modified some text in your widget for example, I think the scrollbar will be impacted.
You may need to catch some of your widget's event to reapply those:
ui->scrollArea->horizontalScrollBar()->setValue(0);
ui->scrollArea->verticalScrollBar()->setValue(0);
If it doesn't help, you should try to debug by tracking scrollbar value with
ui->scrollArea->verticalScrollBar()->value()
and see if your set is well applied, and maybe when it is overriden
Just in case, you may also try some of the methods indicated here, but it's probably not relevant to your issue: setValue of ScrollBar Don't work at first time

How to expand widgets with window resize?

I have a simple qt application with a QTabWidget inside the main window. I also have a few QPushButton(s) and QRadioButton(s).
What I want is that when I resize the window either manually or by maximizing/minimizing it should resize the containers in the same way.
In other words, what I want is equivalent of DockStyle.Fill in qt C++
How can I do that ?
In Qt you have to use Layouts:
The Qt layout system provides a simple and powerful way of automatically arranging child widgets within a widget to ensure that
they make good use of the available space.
In short, all components in a layout will be relocated to new places after the window, to which the layout belongs, is resized.
If you are using deisgner:
1. Click the empty space of a widget to select itself(or a main Window, I use just a base widget here for demonstration), and the layout option will be hightlighted:
2. Choose a desired layout
Here is what object monitor looks like after a QVBoxLayout is used:
If your widget doesn't use layout, it will look like this:
What we have done here is to make the base widget/mainWindow equip a main layout. You can see that the buttons are automatically aligned, when you resize the widget, those component will be relocated according to the layout:
Perhaps you will find it nettlesome of those expanding space, so the next move is to add a Spacer to the layout; so when layout is resized, only the spacer will stretch.
(Another option is to make your widgets expandable, see ** at the end of this post)
3. Besides, you can add a layout into another to create a nested layout
For example, first I choose A and B (by pressing Ctrl) and use QVBoxLayout. This additional layout is not base layout and hence highlighted by red rectangle.
Then I choose C and the layout which contains A & B, and use QHBoxLayout on them,
Finally I use another QVBoxLayout as my main layout on the base widget, just like what we did previously.
And the object monitor:
If you like the special feeling of hitting keyboard and always handcraft the code:
For the last example:
QWidget *Form = new QWidget;
QPushButton *pushButton_A = new QPushButton("A");
QPushButton *pushButton_B = new QPushButton("B");
QPushButton *pushButton_C = new QPushButton("C");
QVBoxLayout *verticalLayout = new QVBoxLayout;
QHBoxLayout *horizontalLayout = new QHBoxLayout;
QVBoxLayout *mainLayout = new QVBoxLayout;
verticalLayout->addWidget(pushButton_A);
verticalLayout->addWidget(pushButton_B);
horizontalLayout->addWidget(pushButton_C);
horizontalLayout->addLayout(verticalLayout);
mainLayout->addLayout(horizontalLayout);
Form->setLayout(mainLayout);
Form->show();
In your case
Here is an example of layout:
Notice that QMainWidget has a centralwidget as a base widget. Besides, each tab of QTabWidget has it's own base widget (tab and tab_2 in the picture) which adopts another base layout.
*Don't forget to add Spacer in layouts to shape them as you like.
** You can set size policy on each widget (QTabWidget, QPushButton etc) to make them horizontally/vertically expandable or fixed, this cooperates with the layout strategy. For example, in the very begin example if we set
button A to be vertically fixed, horizontally expanding
button B to be vertically expanding, horizontally expanding
button C to be vertically expanding, horizontally fixed
It will look like this when resizing:
you need to look into how to use layouts in your application
http://qt-project.org/doc/qt-4.8/layout.html
As a quick and simple first try, in the Designer you can right-click on the main window, and choose "layout" from the drop-down menu. Here you can pick the grid layout, for instance.

QSpacerItem In QFormLayout - Vertical Expand

I would like to force an expanding space in my QFormLayout, but no matter what QFormLayout only uses the QSpaceItem::sizeHint(). Does anyone know a way around this, or the proper way to handle this?
MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
SetupLayout();
}
void MyWidget::SetupLayout()
{
QFormLayout * layout = new QFormLayout();
layout->addRow("Something1", new QComboBox());
layout->addRow("Something2", new QSpinBox());
//Spacer
layout->addItem(new QSpacerItem(0,10, QSizePolicy::Expanding, QSizePolicy::Expanding));
layout->addRow(QPushButton("Something3"));
setLayout(layout);
}
So there were a few different issues:
QFormLayout do not expand like other layouts. My widgets (a few of them) were being placed into a QFormLayout. This prevented them from expanding. I switched my main parent layout from QFormLayout to QVBoxLayout. This made me have to use QLayout::setAlignment(Qt::AlignTop)
This fixed a few problems with a few of my other widgets not expanding. However these widgets used QVBoxLayout. The widget above uses a QFormLayout. To get this expand, I had to use the following line in my QSpacerItem:
QSpacerItem * my_spacer = new QSpacerItem(0,1000, QSizePolicy::Expanding, QSizePolicy::Expanding);
I am supplying some example code. The goal is to show the hierarchy, and where QFormLayout would cause trouble.
Example code:
//A main Widget class
void SetupLayout()
{
QHBoxLayout * main_layout = new QHBoxLayout();
main_layout->addWidget(Some_Widget);
//Create a control widget
control_widget = new QWidget(); // IMPORTANT control_widget is a member
QVBoxLayout * layout = new QVBoxLayout(); //IMPORTANT!!!! - Here it was QFormLayout
layout->setAlignment(Qt::AlignTop); //IMPORTANT - Needed this after switching to QVBoxLayout
layout->addWidget(new QComboBox("stuff")); //Some combo box
control_widget->setLayout(layout);
main_layout->addWidget(control_widget);
}
//Later on, we have a "Put a new widget in the control area" task
void NewControlArea()
{
if(current_control)
control_widget->removeWidget(current_control); //current_control is a member variable
current_control = new MyWidget(); //FROM ABOVE
control_widget->addWidget(current_control);
}
If MyWidget uses a QFormLayout, things are not expanded unless I add spacers with size hints. However, if MyWidget uses a QVBoxLayout, any QWidgets inside it are expanded correctly.
After lot of time with manual as well as lots of tries i guess it's impossible to do what you want using QFormLayout.
This layout is desinged for windows with lot of fields to fill, but only for that.
If you want to add bigger spacing between sections of your form you can use QVBoxLayout with a couple of QFormLayout's inside it separated by spacings.
Notice that in this case each section will have own width of first and second column so maybe that is not the best solution.
The other solution (if we are talking about grouping some options) is to use a couple of QGroupBoxes with QFormLayouts in it. The groups will not be separated by growing spacing, but it will be very readable and you can name your groups. If grouping options is what you want to do - this is probably the most common and user friendly way to do this.
If you only want visual effect you pointed - columns with same width in every section and growing spacing between sections, you can use QGridLayout with 2 columns and add spacers in rows between sections. In this case you have to create QLabel to put into first column by yourself.
Just for posterity, I was having a similar problem. I found that having an organization like the following would cause anything in the inner layout (QHBoxLayout) to not expand vertically as they would if I had dropped them into the QFormLayout by themselves:
QFormLayout
-QHBoxLayout
--QListWidget
However, if I added a layer of indirection by putting the HBoxLayout into a QWidget, then sizing worked correctly:
QFormLayout
-QWidget
--QHBoxLayout
---QListWidget
So you might try adding a QWidget in there and putting your spacer inside of it.
What I did is probably a bit of hacking and is not very elegant, yet it did the trick in just one row:
addRow(" ", (QWidget*)nullptr);
This doubles the space between rows added before and after this call.
I suspect that MyWidget has the wrong size. The layout will use the widget's size to work out how best to layout its own items. Just because one of those items is set to an expanding policy does not mean that the layout will force the size of MyWidget to expand. If the size of MyWidget is fixed there is nothing the internal layout can do.
If you make MyWidget bigger you should see the layout working as you hope. Perhaps you need to put MyWidget in a vertical layout with its policy set to expanding? Without knowing how MyWidget gets its size it's hard to be sure.