How to create custom widget and use it in Qt Designer? - c++

I extremely need to create my custom widget and use it inside QtDesigner ( promoting QWidget to my widget ). I have never done it before, and can't google anything useful. Widget i need to get is just square box with few QLabel and QLineEdit objects. For this moment i have the following code:
#include "customwidget01.h"
#include "qlabel.h"
#include "qlineedit.h"
#include "QGridLayout"
customWidget01::customWidget01(QWidget *parent) : QWidget(parent)
{
QString textSheets = "QLabel,QLineEdit {width:60;height:20;max-width:60;max-height:20;;min-width:60;min-height:20;}";
QString widgetSheet = "customWidget01 {width:200;height:200;max-width:200;max-height:200;;min-width:120;min-height:200;}";
this->setStyleSheet(widgetSheet + textSheets);
QLabel *label1= new QLabel(this);
label1->setText("1st arg");
QLabel *label2 = new QLabel(this);
label2->setText("2nd arg");
QLabel *label3= new QLabel(this);
label3->setText("3rd arg");
QLabel *label4= new QLabel(this);
label4->setText("4th arg");
QLineEdit *line1 = new QLineEdit(this);
line1->setPlaceholderText("enter 1st arg");
QLineEdit *line2 = new QLineEdit(this);
line2->setPlaceholderText("enter 2nd arg");
QLineEdit *line3 = new QLineEdit(this);
line3->setPlaceholderText("enter 3rd arg");
QLineEdit *line4 = new QLineEdit(this);
line4->setPlaceholderText("enter 4th arg");
QGridLayout *layout = new QGridLayout();
this->setLayout(layout);
layout->setVerticalSpacing(10);
layout->setHorizontalSpacing(10);
layout->addWidget(label1,0,0);
layout->addWidget(label2,1,0);
layout->addWidget(label3,2,0);
layout->addWidget(label4,3,0);
layout->addWidget(line1,0,1);
layout->addWidget(line2,1,1);
layout->addWidget(line3,2,1);
layout->addWidget(line4,3,1);
this->setVisible(true);
}
My problems are:
cant draw border around widget itself
vertical and horizontal spacings do not work
Used QtDesigner for GUI all the time - not really familiar with gui creation in plain code.

let me help you in order to get beautiful interface you need to learn CSS
I will show you how it works
that's what you have right now
This means that you do not correctly write the CSS code
QString textSheets = "QLabel,QLineEdit {width:60;height:20;max-width:60;max-height:20;;min-width:60;min-height:20;}";
QString widgetSheet = "customWidget01 {width:200;height:200;max-width:200;max-height:200;;min-width:120;min-height:200;}";
this->setStyleSheet(widgetSheet + textSheets); // does not work
I will exchange these lines for it
QString textSheets = "QLineEdit{ border-width: 2px; border-style: solid; border-color: red green black rgb(127,255,10); }"
"QLabel { border-width: 2px; border-style: solid; border-color: green black rgb(10,255,180) rgb(180,10,158); }" ;
setStyleSheet(textSheets);
and that's what result
to resize you just need to do so
//label1->setMinimumSize(150,50);
label1->setFixedSize(150,50);
//label1->setMaximumSize(150,50);
//label1->setMidLineWidth(150);
and that's what result

Add a QWidget in design mode.
Right click it and select Promote to... from the context menu.
Write the name (customWidget01) of your from QWidget derived class into Promoted class name.
Make sure the generated text in Header file is correct.
Click add.
Select it and click promote.

Related

Issue change tab QTabWidget & QScrollArea Qt

I'm trying to create a QScrollArea in a QTabWidget.
Versions :
Qt 5.15.0
Qt creator 4.12.4
MSVC2019 64 bits
First of all, I've created the QTabWidget :
tabWidget = new QTabWidget(this);
tabWidget->setGeometry(10, 15, 1200, 665);
tabWidget->setStyleSheet("font-size : 15px");
tab1Content = new QWidget(tabWidget); tabWidget->addTab(tab1Content, "tab1");
tab2Content = new QWidget(tabWidget); tabWidget->addTab(tab2Content, "tab2");
tab3Content = new QWidget(tabWidget); tabWidget->addTab(tab3Content, "tab3");
tab4Content = new QWidget(tabWidget); tabWidget->addTab(tab4Content, "tab4");
I can add
tabWidget->setEnable(true);
And for all tabs, 0 <= i < tabWidget.count
tabWidget->setTabEnabled(i, true);
Click to change tab doesn't work : https://i.stack.imgur.com/8r1Jg.png
Strange thing : color looks like enabled but i can only change tabs with ← → and when i lost tabWidget focus by clicking on an other thing outside the tabWidget, i can't regain focus.
So i've created temporary button to change tabs and linked to tabWidget like that :
connect(changeTab, &QPushButton::clicked, [&]() {onChangeTab();});
void MainWindow::onChangeTab() {
tabWidget->setCurrentIndex(tabWidget->currentIndex() >= tabWidget->count() - 1 ? 0 : tabWidget->currentIndex() + 1);
}
It works well.
Thus, I've start to create the QScrollArea :
First, it doesn't work, so I've tried to found sth on internet :
QScrollArea not working as expected with QWidget and QVBoxLayout
My result : https://i.stack.imgur.com/jvVol.png
I cannot click on a single button and i can't scroll...
And if i try to force scroll like this, it doesn't scroll
scrollArea->scroll(0, 50);
Last thing, there isn't infinite loop or dead lock things because all things around this cursed tabWidget and scroll Area work perfectly.
I don't know why these objects "don't answer" if somedoby had this kind of experiment could you help me please ?
Thank you very much in advance.
try this code
#include "widget.h"
#include<QTabWidget>
#include<QLabel>
#include<QVBoxLayout>
#include<QScrollArea>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QTabWidget *tabWidget = new QTabWidget(this);
tabWidget->setGeometry(10, 15, 1200, 665);
tabWidget->setStyleSheet("font-size : 15px");
QWidget * tab1Content = new QWidget;
//preparing tab1content ( e.g.)
QVBoxLayout * verticalLayout = new QVBoxLayout;
// adding items to vertical layout
for(int i=0;i<100;i++)
verticalLayout->addWidget(new QLabel(QString::number(i)));
// set this vertical layout inside tab1content
tab1Content->setLayout(verticalLayout);
// create new scroll area ...
QScrollArea * scroll = new QScrollArea;
// ... and add tab1content in scroll area
scroll->setWidget(tab1Content);
// and finally add scroll area inside tabwidget
tabWidget->addTab(scroll,"tab1");
QWidget * tab2Content = new QWidget; tabWidget->addTab(tab2Content, "tab2");
QWidget * tab3Content = new QWidget; tabWidget->addTab(tab3Content, "tab3");
QWidget * tab4Content = new QWidget; tabWidget->addTab(tab4Content, "tab4");
}
Widget::~Widget()
{
}

Qt StyleSheet to programmatically createdQWidget

I want to apply a stylesheet to a particular Qwidget that I create in the constructor of the parent QWidget. I don't want to create the QWidget in the Designer, but I want to create it dynamically.
This is my code
enum {one = 0,
two = 1,
three = 2};
cMainForm::cMainForm(QWidget *parent) : QWidget(parent), ui(new Ui::cMainForm) {
//...
QWidget* widgetTest[3];
widgetTest[one] = new QWidget(this);
widgetTest[one]->setGeometry(100,100,100,100);
widgetTest[one]->show();
widgetTest[one]->raise();
//...
setStyleSheet("QWidget#widgetTest[one]{"
"background-color: red;"
"}"
);
//...
}
And doesn't work.
If I change the styleSheet:
setStyleSheet("QWidget{"
"background-color: red;"
"}"
);
The stylesheet is applied to all the widgets. But I don't want this; I want to apply the stylesheet only to that particular widget.
Also if I don't use an array, it doesn't work.
QWidget* widgetTest;
widgetTest = new QWidget(this);
widgetTest->setGeometry(100,100,100,100);
widgetTest->show();
widgetTest->raise();
//...
setStyleSheet("QWidget#widgetTest{"
"background-color: red;"
"}"
);
I already searched the documentation.
What's the solution?
The selector you're using (#) refers to the widget objectName property, not the variable name (the style engine knows nothing about your variables). Give the widget an object name:
widgetTest->setObjectName("widgetTest");
then set the stylesheet:
widgetTest->setStyleSheet("QWidget#widgetTest { background-color: red }");

QTreeWidget with non-native scroll bar when background changed

I need a QTreeWidget with transparent background so it has the same color as the native light-gray window background. This works fine by setting the background to transparent.
The problem is that if I do this, the scroll becomes non-native looking. The default background of QTreeWidget is "white" and if I don't change it, the scroll bar does look native. However, if I change the background to "transparent", the scrollbar looses its native appearance.
To demonstrate this, I put two QTreeWidgets next to each other, one with the default white background showing the native scroll bar and one with the background changed to transparent, showing a non-native scroll bar: screenshot
Here is the code:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QHBoxLayout* layout = new QHBoxLayout(this);
ui->centralWidget->setLayout(layout);
QTreeWidget* tree1 = new QTreeWidget();
QTreeWidget* tree2 = new QTreeWidget();
layout->addWidget(tree1);
layout->addWidget(tree2);
// add ten items to each tree widget
for(int i=0; i<10; i++){
QString item_text = "item " + QString::number(i);
QTreeWidgetItem* item1 = new QTreeWidgetItem();
item1->setText(0, item_text);
tree1->addTopLevelItem(item1);
QTreeWidgetItem* item2 = new QTreeWidgetItem();
item2->setText(0, item_text);
tree2->addTopLevelItem(item2);
}
// change the background color of tree2 to the window color
// this leads to a non native scroll bar for tree2
tree2->setStyleSheet("background-color: transparent;");
}
How can I have the transparent background an still keep the native scroll bar?
I finally found the solution. I need to restrict the definition of the background-color to the QTreeWidget:
tree2->setStyleSheet("QTreeWidget {background-color: transparent;}");

QWidget's background applied to all its QWidget children

I chose to use Qt to manage the GUI of a project I am working on.
After finding how to apply a picture at the bottom of my QWidget, I noticed that it has an impact on all the components that are added to it.
Whatever the style applied through the setStyleSheet method or even with a QPixmap, the background of these elements is always the image defined for the QWidget container.
How can I avoid this behavior ?
Here is my code :
MainMenu::MainMenu(QWidget* Parent, const QPoint& Position, const QSize& Size) : QWidget(Parent) {
QString qwidgetStyle = "QWidget {background-image: url(background.jpg); border: 5px solid rgba(3, 5, 28, 1);}";
QString buttonStyle = "color: rgba(73, 123, 176, 1); font-size:30px; background-color: rgba(73, 123, 176, 1);";
move(Position);
resize(Size);
setStyleSheet(qwidgetStyle);
// Menu title
QLabel *title = new QLabel(this);
title->setText("Menu");
title->setStyleSheet(buttonStyle);
title->setAlignment(Qt::AlignCenter);
// Menu buttons
// Play
buttonPlay = new QPushButton("Play");
(*buttonPlay).setEnabled(true);
(*buttonPlay).setStyleSheet(buttonStyle);
connect(buttonPlay, SIGNAL(clicked()), this, SLOT(handleButton()));
// Option
buttonOptions = new QPushButton("Options", this);
(*buttonOptions).setEnabled(true);
(*buttonOptions).setGeometry(250, 175, 100, 50);
(*buttonOptions).setStyleSheet(buttonStyle);
connect(buttonOptions, SIGNAL(clicked()), this, SLOT(handleButton()));
// Quit
buttonQuit = new QPushButton("Quit", this);
(*buttonQuit).setEnabled(true);
(*buttonQuit).setGeometry(250, 275, 100, 50);
(*buttonQuit).setStyleSheet(buttonStyle);
connect(buttonQuit, SIGNAL(clicked()), this, SLOT(handleButton()));
// Layout
QGridLayout *layout = new QGridLayout;
layout->setMargin(50);
layout->addWidget(title, 0, 0, 1, 5);
layout->addWidget(buttonPlay, 3, 1, 2, 3);
layout->addWidget(buttonOptions, 4, 1, 2, 3);
layout->addWidget(buttonQuit, 5, 1, 2, 3);
setLayout(layout);
show();
}
The behavior you encountered is perfectly normal, because of the following lines :
QString qwidgetStyle = "QWidget {background-image: url(background.jpg); border: 5px solid rgba(3, 5, 28, 1);}";
...
setStyleSheet(qwidgetStyle);
Here, you just told Qt to apply qwidgetstyle to every QWidget of your application, with the keyword QWidget. That's why in Qt, you better set a name to your object if you want to apply a style to this particular object.
In your code, QLabel and QPushButton both inherit from QWidget, so they will have the style you defined for a QWidget, unless you name them or you specify the style for each one.
If you want to set style sheet for your MainMenu which inherits directly from QWidget (which is what you are doing in the first place), you have to set a name, and then apply the style :
setObjectName("MainMenu");
QString qwidgetStyle = "QWidget#MainMenu {background-image: url(background.jpg); border: 5px solid rgba(3, 5, 28, 1);}";
setStyleSheet(qwidgetStyle); // here, only your MainMenu will have the style "qwidgetstyle"
Notice that you can, for example, set the same style sheet for every QWidget, and only add a particular color for your MainMenu :
// this is in a CSS, but you can apply it directly from the MainMenu constructor of course
QWidget, QWidget#MainMenu {
background-image: url(background.jpg);
border: 5px solid rgba(3, 5, 28, 1);
} // aplied to all QWidget
QWidget#MainMenu {
color : #9b9b9b; // a nice grey, only applied to MainMenu
}
Again, be specific when using style sheets or you will end up having strange colors/alignments everywhere in your application :). Hope that helps!
NB : you can also thank #PaulRooney who gave a very good link in the comments.

How to set text color in QLineEdit when background image is set for QlineEdit

I have a QLineEdit and i have set an image to QStackedWidget. Now i want to change the font color of Texts which is in QLineEdit. How to do it?
QLineEdit *line1 = new QLineEdit("Hello");
QStackedWidget *stack1 = new QStackedWidget();
stack1->addWidget(line1);
stack1->setStyleSheet("background-image: url(black.gif);");
I tried writing foreground-color and foreground in setStyleSheet. But its not work for me.
This worked for me :
QPalette *palette = new QPalette();
palette->setColor(QPalette::Text,Qt::red);
line->setPalette(*palette);
Normally, this can be achieved by setting the color stylesheet property, so no foreground-color or something like that. So this should do it:
QLineEdit *line1 = new QLineEdit("Hello");
QStackedWidget *stack1 = new QStackedWidget();
stack1->addWidget(line1);
stack1->setStyleSheet("background-image: url(black.gif); color: #FFFFFF");