I am struggling with a basic StyleSheet question. I am trying to apply a stylesheet to a QFrame within a MainWindow, and for some reason, the stylesheet is being ignored. This seems related to Qt Stylesheet for custom widget and Enable own widget for stylesheet, but I've tried adding a paintEvent and that did not help. Its gotta be something simple, but I can't see it. Can anyone help?
main.cpp:
#include <QApplication>
#include <QDebug>
#include "mainwindow.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindowDef mainWindow;
mainWindow.show();
return app.exec();
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
class MainWindowDef : public QMainWindow {
Q_OBJECT
public:
MainWindowDef(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *);
};
#endif
mainwindow.cpp:
#include <QDebug>
#include "mainwindow.h"
MainWindowDef::MainWindowDef(QWidget *parent) : QMainWindow(parent) {
QFrame *frame = new QFrame;
QVBoxLayout *layout = new QVBoxLayout;
QPushButton *button = new QPushButton("Press");
layout->addWidget(button);
QString myStyle = QString( "QFrame {"
"border: 2px solid green;"
"border-radius: 4px;"
"padding: 2px"
"background-color: red;"
"color: blue;"
"}");
frame->setStyleSheet(myStyle);
frame->setLayout(layout);
frame->setAutoFillBackground(true);
setCentralWidget(frame);
}
void MainWindowDef::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
I finally figured this out. It was missing a semicolon.
"padding: 2px"
should say:
"padding: 2px;"
Sigh.
Related
I'm working in ubuntu kde 20.04, qt5.15
I my purpose was to create a QPushButton that change his color when he got clicked, then I created a new derived class for doing this (Facelet), it works but the colors I got are not those I was assuming to get.
Facelet.h
#ifndef FACELET_H
#define FACELET_H
#include <QPushButton>
class Facelet : public QPushButton
{
Q_OBJECT
public:
explicit Facelet(QWidget * parent = nullptr);
explicit Facelet(int color, QWidget *pareny = nullptr);
void reset();
static QString colors[6];
private slots:
void __change_color();
private:
int _ColorIndex;
};
#endif // FACELET_H
Facelet.cpp
#include "Facelet.h"
QString Facelet::colors[6] = { "background-color: yellow;", "background-color: red;", "background-color: green;", "background-color: rgb(255, 130, 50);", "background-color: blue;", "background-color: white;" };
enum { rxyellow, rxred, rxgreen, rxorange, rxblue, rxwhite };
//public
Facelet::Facelet(QWidget *parent) :
QPushButton(parent),
_ColorIndex(-1)
{
this->resize(75, 75);
this->setStyleSheet("background-color: gray");
connect(this, SIGNAL(clicked()), SLOT(__change_color()));
}
Facelet::Facelet(int color, QWidget* parent) :
QPushButton(parent),
_ColorIndex(color)
{
this->resize(75, 75);
this->setStyleSheet(colors[_ColorIndex]);
connect(this, SIGNAL(clicked()), SLOT(__change_color()));
}
void Facelet::reset() {
this->setStyleSheet("background-color: gray");
}
//private
void Facelet::__change_color() {
_ColorIndex = (_ColorIndex >= 5 ) ? 0 : (_ColorIndex + 1);
this->setStyleSheet(colors[_ColorIndex]);
}
And here my main.cpp
#include <QApplication>
#include <QMainWindow>
#include "Facelet.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
Facelet f;
w.setCentralWidget(&f);
w.show();
return a.exec();
}
See? The screen is faded, I want a uniform strong color. What's wrong with my code?
To correct that I found two solution via reimplementation od paintEvent method.
first
void Facelet::paintEvent(QPaintEvent*) {
QPainter p(this);
p.setOpacity(1.0);
}
the first one is pretty easy, reading some topic I found out that a QWidget to have a setStyleSheet(QString) methods working properly need the following line in the paintEvent(QPaintEvent*) method as the official documentation says
void Facelet::paintEvent(QPaintEvent *) {
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
I have written a simple program where the dialog window opens in maximized mode and there are some labels and buttons set to this window. I set a gridlayout to my window and added the labels and buttons to the layout , and my code worked fine. When I try to use scrollarea instead of the pink label(which is in row=1 and column=1), I don't get the same result that I got from putting the pink label in (row=1 and column=1).
I know that when labels or buttons are supposed to be in a scrollarea, I must declare a widget and setwidget to the scrollarea, then declare a layout and setlayout to the widget. But for this case(that the scrollarea itself must be in a layout) I don't know what to do.
Here is the code:
dialog.h:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QScrollArea>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
QLabel *red_label;
QLabel *pink_label;
QLabel *yellow_label;
QScrollArea *scrollArea;
QPushButton *button_one;
QPushButton * button_two;
QPushButton * button_three;
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
dialog.cpp:
#include "dialog.h"
#include "ui_dialog.h"
#include <QLabel>
#include <QGridLayout>
#include <QWidget>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
this->setWindowState(this->windowState() ^ Qt::WindowMaximized);
this->setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint |
Qt::WindowMaximizeButtonHint);
red_label = new QLabel(this);
red_label->showFullScreen();
red_label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
red_label->setLayoutDirection(Qt::RightToLeft);
red_label->setObjectName("forlumha_Name");
red_label->setStyleSheet(
"QLabel#forlumha_Name {"
"background-color:red;"
"}"
);
/* pink_label = new QLabel(this);
pink_label ->showFullScreen();
pink_label ->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
pink_label ->setLayoutDirection(Qt::RightToLeft);
pink_label ->setObjectName("forlumha_Name");
pink_label ->setStyleSheet(
"QLabel#forlumha_Name {"
"background-color:pink;"
"}"
);*/
yellow_label = new QLabel(this);
yellow_label->showFullScreen();
yellow_label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
yellow_label->setLayoutDirection(Qt::RightToLeft);
yellow_label->setObjectName("forlumha_Name");
yellow_label->setStyleSheet(
"QLabel#forlumha_Name {"
"background-color:yellow;"
"}"
);
button_one = new QPushButton(this);
button_one->setFixedSize(50,50);
button_two = new QPushButton(this);
button_two->setFixedSize(50,50);
button_three = new QPushButton(this);
button_three->setFixedSize(50,50);
//.......adding scrollarea........//
scrollArea = new QScrollArea(this);
//..........set layouts......//
QGridLayout *layout = new QGridLayout();
this->setLayout( layout );
layout->addWidget(red_label,0,0,15,1);
layout->addWidget(yellow_label,0,1,1,1);
//layout->addWidget(pink_label,1,1,14,1);
layout->addWidget(scrollArea,1,1,14,1);
layout->addWidget(button_one,6,2,1,1);
layout->addWidget(button_two,7,2,1,1);
layout->addWidget(button_three,8,2,1,1);
}
Dialog::~Dialog()
{
delete ui;
}
main.cpp:
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
The above code output :
When I comment the pink_label parts and declare a scrollArea and put it in row=1 and column=1,the output is :
In this code which can able to play video and play *.mp3. code works properly,in my mainwindow.ui I added widget called widgetGif by drag and drop .This widget containing label also. but this widget not visible when I run the program. How can I display this widget called widgetGif
here is part of my code :
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMovie>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
player = new QMediaPlayer(this);
vw = new QVideoWidget (this);
player->setVideoOutput(vw);
this->setCentralWidget(vw); //I think this is the reason
slider = new QSlider(this);
bar = new QProgressBar(this);
slider->setOrientation(Qt::Horizontal);
ui->statusBar->addPermanentWidget(slider);
ui->statusBar->addPermanentWidget(bar);
connect(player,&QMediaPlayer::durationChanged,slider,&QSlider::setMaximum);
connect(player,&QMediaPlayer::positionChanged,slider,&QSlider::setValue);
connect(slider,&QSlider::sliderMoved,player,&QMediaPlayer::setPosition);
connect(player,&QMediaPlayer::durationChanged,bar,&QProgressBar::setMaximum);
connect(player,&QMediaPlayer::positionChanged,bar,&QProgressBar::setValue);
sliderVolumn = new QSlider(this);
sliderVolumn->setOrientation(Qt::Horizontal);
ui->statusBar->addPermanentWidget(sliderVolumn);
connect(sliderVolumn,&QSlider::sliderMoved,player,&QMediaPlayer::setVolume);
QMovie *movie=new QMovie(":/res/icons/giphy.gif");
if (!movie->isValid())
{
// Something went wrong :(
}
ui->labelGif->setMovie(movie);
movie->start();
ui->widgetGif->setVisible(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionOpen_triggered()
{
QString filename= QFileDialog::getOpenFileName(this,"Open Folder","","Open a File(*.*)");
on_actionStop_triggered();
player->setMedia(QUrl::fromLocalFile(filename));
on_actionPlay_triggered();
if(filename.endsWith(".mp3")){
qDebug() << " file is mp3";
}else{
qDebug() << " not is mp3";
}
}
QMainWindow needs a centralWidget. You must use layouts to include your QVideoWidget and also your widgetGif and then set it as centralWidget of the QMainWindow.
In the following example, textEdit would be your QVideoWidget and the object label is like your widgetGif.
We have also two buttons to hide or show label using the method setVisible.
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class QLabel;
class QPushButton;
class QTextEdit;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QWidget *centralWidget;
QLabel *label;
QPushButton *pushButton;
QPushButton *pushButton_2;
QTextEdit *textEdit;
public slots:
void showSlot();
void hideSlot();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Vertical layout
QVBoxLayout *mainLayout = new QVBoxLayout;
// Widgets
centralWidget = new QWidget(this);
label = new QLabel();
pushButton = new QPushButton();
pushButton_2 = new QPushButton();
textEdit = new QTextEdit();
// Title and texts
this->setWindowTitle("MainWindow");
label->setText("TextLabel");
pushButton->setText("Show");
pushButton_2->setText("Hide");
// Add widgets to layout
mainLayout->addWidget(textEdit);
mainLayout->addWidget(label);
mainLayout->addWidget(pushButton);
mainLayout->addWidget(pushButton_2);
centralWidget->setLayout(mainLayout);
// Set the central widget
this->setCentralWidget(centralWidget);
connect(pushButton, SIGNAL (clicked()), this, SLOT (showSlot()));
connect(pushButton_2, SIGNAL (clicked()), this, SLOT (hideSlot()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showSlot()
{
label->setVisible(true);
}
void MainWindow::hideSlot()
{
label->setVisible(false);
}
I have a display window like this:
Above display widgets are QGraphicsView widgets (they are in a QGridLayout) and what I want to achieve is that:
when user click in MainWindow, I want to seize that clicked position and decide which QGraphicsView widget contains that position and set the border of that selected QGraphicsView widget to green color. And only one QGraphicView widget can be selected at a time.
Can anyone give me some ideas?
Thanks
You can use installEventFilter for your QGraphicsViews and detect mouse press events on them. So, you can define current view and make border for it as you want. Small example:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsView>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public:
bool eventFilter(QObject* watched, QEvent* event) override;
private:
Ui::MainWindow *ui;
QGraphicsView* view1_;
QGraphicsView* view2_;
QGraphicsView* selectedView_;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGridLayout>
#include <QMessageBox>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
view1_(nullptr),
view2_(nullptr),
selectedView_(nullptr)
{
ui->setupUi(this);
QGridLayout* grid = new QGridLayout(this->centralWidget());
view1_ = new QGraphicsView(this);
view2_ = new QGraphicsView(this);
grid->addWidget(view1_, 0, 0);
grid->addWidget(view2_, 0, 1);
view1_->viewport()->installEventFilter(this);
view2_->viewport()->installEventFilter(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::eventFilter(QObject* watched, QEvent* event)
{
qDebug() << event->type();
if (event->type() == QEvent::MouseButtonPress)
{
if (watched == view1_->viewport()){
selectedView_ = view1_;
QMessageBox::information(this, "!", "First");
return false;
}
else if (watched == view2_->viewport()){
selectedView_ = view2_;
QMessageBox::information(this, "!", "Second");
return false;
}
}
return QMainWindow::eventFilter(watched, event);
}
If you only want to change the border color on mouse hover, you wouldn't need such complicated programming. Qt supports style sheets, just like CSS.
In this case, it's enough to attach the following stylesheet to your MainWindow.
QGraphicsView:hover {
border-style: solid;
border-width: 2px;
border-color: green;
}
There's two ways to get this done:
Using the Designer: First select the MainWindow and then in its properties panel click on the styleSheet and copy and paste the style sheet.
Using code: Use setStyleSheet(...) method of QMainWindow and pass the style sheet as a string.
I am a QT newbie and trying to play around with Apps. I have just coded a very trivial App with some buttons. The main idea is to have a small "logo" in my App. LAter I would like to add some background image as well.
I have coded from an example App with a grid layout within which is a QBoxLayout which groups my buttons.
As you can see in my code, I have tried adding the Logo everywhere. When I added it in main.cpp, I have two views one showing buttons and the other my logo. Of course I do not want this. So I tried adding it in mainwindow.cpp but in this case, I don't see my Logo appearing anywhere at all :(
Please advise.
Here is the code:
main.cpp:
#include <QtGui/QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window window;
window.show();
/*
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsPixmapItem item(QPixmap("/home/marc/Desktop/Niranjana/Images/logo.9.png"));
scene.addItem(&item);
view.show();
*/
return a.exec();
}
mainwindow.h
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
#include <QRadioButton>
class QGroupBox;
class Window : public QWidget
{
Q_OBJECT
public:
Window(QWidget *parent = 0);
void onCheck_remote(int flag);
void onCheck_local(int flag);
private:
QRadioButton *button_local;
QRadioButton *button_remote;
QGroupBox *createPushButtonGroup();
};
#endif
mainwindow.cpp
#include <QtGui>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include "mainwindow.h"
Window::Window(QWidget *parent)
: QWidget(parent)
{
QGridLayout *grid = new QGridLayout;
QGraphicsScene scene;
QGraphicsPixmapItem item(QPixmap("/home/test/logo.png"));
QGraphicsView view(&scene);
scene.addItem(&item);
view.show();
grid->addWidget(view.viewport(), 1, 1);
grid->addWidget(createPushButtonGroup(), 2, 1);
setLayout(grid);
setWindowTitle(tr("My App"));
resize(480, 420);
}
QGroupBox *Window::createPushButtonGroup()
{
QGroupBox *groupBox = new QGroupBox();
/*
QGraphicsScene scene;
QGraphicsPixmapItem item(QPixmap("/home/marc/Desktop/Niranjana/Images/logo.9.png"));
QGraphicsView view(&scene);
scene.addItem(&item);
scene.setBackgroundBrush(Qt::white);
view.show();
*/
QPushButton *button1 = new QPushButton(tr("&Start"));
QPushButton *button2 = new QPushButton(tr("&Stop"));
button_local = new QRadioButton(tr("&with power"));
button_remote = new QRadioButton(tr("without power"));
button_local->setChecked(1);
QVBoxLayout *vbox = new QVBoxLayout;
// vbox->addSpacing(10);
// vbox->addWidget(view.viewport());
//vbox->addSpacing(10);
vbox->addWidget(button1);
vbox->addSpacing(10);
vbox->addWidget(button2);
vbox->addSpacing(50);
vbox->addWidget(button_local);
vbox->addWidget(button_remote);
vbox->addStretch(1);
groupBox->setLayout(vbox);
return groupBox;
}
You should
Make your scene, view, item pointer members of your window class
Instantiate them in your Window ctor
do grid->addWidget(view, 1, 1);
Otherwise, all the items instantiated on the stack in the ctor will get deleted when exiting.