Styl i dziedziczenie po QWidget

0

Mam QWidget na nim QLabel i QProgressBar, ustawiam styl

    QWidget *w = new QWidget(this);
    QLabel *label = new QLabel;
    label->setAlignment(Qt::AlignCenter);
    label->setText("buuuuu");


    QVBoxLayout  *verticalLayout = new QVBoxLayout(w);

    QProgressBar *progressBar = new QProgressBar(w);
    progressBar->setValue(24);
    progressBar->setTextVisible(false);

    verticalLayout->addWidget(label);
    verticalLayout->addWidget(progressBar);

    // troche koloru aby było wiadomo gdzie sie kończy i zaczyna QLabel
    QString s = "";
    s += "QWidget {  font:  14px;  background-color: gray; border-style: outset; border-width: 2px; border-radius: 10px;  border-color: black;     }" ; // background-color: #00FF00;  font-size: 26px;
    s += "QLabel {  font: bold 14px;  color: white;  background-color: blue; }" ;
    s += "QProgressBar {  border-radius: 10px; }" ;
    w->setStyleSheet(s);

    w->move(433,32);
    w->resize(200,100);
    w->show();

I wszystko działa zgodnie z planem
image

To samo ale dziedziczę po QWidget

Koza::Koza(QWidget *parent)
    : QWidget{parent}
{
    QString s = "";
    s += "Koza {  font:  14px;  background-color: gray; border-style: outset; border-width: 2px; border-radius: 10px;  border-color: black;     }" ; // background-color: #00FF00;  font-size: 26px;
    s += "QWidget {  font:  14px;  background-color: gray; border-style: outset; border-width: 2px; border-radius: 10px;  border-color: black;     }" ; // background-color: #00FF00;  font-size: 26px;
    s += "QLabel {  font: bold 14px;  color: white;  background-color: blue; }" ;
    s += "QProgressBar {  border-radius: 10px; }" ;
    setStyleSheet(s);


    QLabel *label = new QLabel;
    label->setAlignment(Qt::AlignCenter);
    label->setText("buuuuu");


    QVBoxLayout  *verticalLayout = new QVBoxLayout;

    QProgressBar *progressBar = new QProgressBar;
    progressBar->setValue(24);
    progressBar->setTextVisible(false);

    verticalLayout->addWidget(label);
    verticalLayout->addWidget(progressBar);
    setLayout(verticalLayout);

}

I już nie działa poprawnie bo QWidget nie ma obramowania i koloru
image
W przypadku dziedziczenia coś trzeba jeszcze dodać aby komponent reagował na styl ?

pliki nienazwany39.zip

4

Pierw, musisz przepuścić koza.h przez MOC:

qt5_wrap_cpp(PROJECT_SOURCES
    koza.h
)

Następnie musisz zaimplementować paintEvent() (linki: SO / Doc Qt)

#include <QWidget>
class QPaintEvent;
class Koza : public QWidget
{
    Q_OBJECT
public:
    explicit Koza(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent*) override;
signals:

};
void Koza::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

I to działa ładnie.

0

Dziękuje,
działa ładnie rzekłbym nawet że cudnie ,
a jest jakaś subtelna różnica pomiędzy "qt5_wrap_cpp" per pliki a set(CMAKE_AUTOMOC ON) dla całego projektu ?
QtCreator tworząc nowy projekt proponuje to drugie rozwiązanie

Czy różnica to tylko czas na parsowanie wszystkich vs wybrane pliki ?

1

@Adamek Adam:
nie wiem czy zwrócisz uwagę na to co ci tutaj przedstawię, możliwe, że o tym wiesz, że takie coś się robi i pewnie umiesz to robić.

Chcę pokazać ci inną możliwość. Bo ja również kiedyś kombinowałem ze stylami setStyleSheet i problem jest taki, że pod linuxem działa, a pod windowsem działa częściowo - więc wykombinowałem sobie taki kawałek kodu

uprzedzam - kod jest taki se, szału nie ma, nie powalę was na kolana ale to działa pod KAŻDYM systemem operacyjnym bez zająknięcia. I nie ma znaczenia jaki styl okien jest aktywny.

plik button.h

#ifndef BUTTON_H
#define BUTTON_H

#include <QPushButton>
#include <QObject>
#include <QWidget>
#include <QEvent>
#include <QHoverEvent>
#include <QPaintEvent>

class MyButton : public QPushButton
{
    Q_OBJECT

public:
    MyButton(QWidget *parent=nullptr);

private:
    void buttonHover(QHoverEvent *ev);
//    void paintEvent(QPaintEvent *) override;
    bool event(QEvent *) override;
};

#endif // BUTTON_H

plik button.cpp

#include "button.h"
#include <QDebug>
#include <QFont>
#include <QPalette>
#include <QPainter>

MyButton::MyButton(QWidget *parent) : QPushButton(parent)
{
    setText("Wciśnij mnie");
}

bool MyButton::event(QEvent *ev)
{
    if(ev->type()==QEvent::HoverEnter){

        QPalette p;
        p.setColor(QPalette::Button,QColor(Qt::green));
        this->setPalette(p);

        QFont font = this->font();
        font.setBold(true);
        this->setFont(font);
        this->repaint();

        qDebug()<<"Enter";
    }
    if(ev->type()==QEvent::HoverLeave){

        QPalette p;
        p.setColor(QPalette::Button,QColor(Qt::red));
        this->setPalette(p);

        QFont font = this->font();
        font.setBold(false);
        this->setFont(font);

        qDebug()<<"Leave";
    }
    return QPushButton::event(ev);
}

plik widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QCloseEvent>
#include <QPushButton>
#include "button.h"

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

protected:
    void closeEvent(QCloseEvent *event);

private:
    MyButton *button;
    QPushButton *button2;
};
#endif // WIDGET_H

plik widget.cpp

#include "widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) : QWidget(parent)
{
    resize(300,200);
    button = new MyButton(this);
}

void Widget::closeEvent(QCloseEvent *event)
{
    event->accept();
    qDebug()<< "close";
}

Widget::~Widget()
{
}

plik main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    a.setStyle("Fusion");
    Widget w;
    w.show();
    return a.exec();
}

screen z działania programu (za każdym najechaniem i odjechaniem myszy z nad buttona) efekt jest taki

po najechaniu na buttona

screenshot-20230228175225.png

po odjechaniu znad buttona

screenshot-20230228175252.png

gdybym był lepszy w te klocki, to najpewniej w ten sposób ostylowałbym sobie całe okno

PS. jak radził tobie @kq żeby nadpisać tą funkcję paintEvent(QPaintEvent *pe) - też kiedyś próbowałem i nie udało mi się to wcale... w każdym razie jest to bardzo ciekawe

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.