Russian Qt Forum

Qt => Вопросы новичков => Тема начата: antonkw от Февраль 27, 2014, 09:54



Название: Перерисовка кнопок
Отправлено: antonkw от Февраль 27, 2014, 09:54
 Добрый день. Уже пару дней гуглю данный вопрос, но так проблему и не решил.
Нужно самому перерисовать кнопку, пусть будет, например, эллипсовидная кнопка, которая при наведении меняет свет. Как правильно перегружать paintEvent? На данный момент сделано так:

Код:
#include <QPushButton>
#include <QPainter>
class CustomButton : public QPushButton
   {
    Q_OBJECT

public:
    CustomButton(QWidget *parent = 0);
    ~CustomButton();

public:
    QString FirstName,MiddleName,Lastname;
    QImage SimileIcon;
    bool IsBkColorEnabled;
    QColor Bkclor;

protected:
    void paintEvent(QPaintEvent *);
};


Код:
CustomButton::CustomButton(QWidget *parent)
    : QPushButton(parent)
{

}

CustomButton::~CustomButton()
{

}

void CustomButton::paintEvent(QPaintEvent *paint)
{
    QPushButton::paintEvent(paint);
    QPainter p(this);
    p.save();                       
    p.setFont(QFont("Arial", 20));
    p.restore();
}

Код:
 button1=new CustomButton;
    button1->setText(" Push");

Но шрифт не меняется, что подскажете (почитать хотя бы)?


Название: Re: Перерисовка кнопок
Отправлено: Old от Февраль 27, 2014, 10:11
Так вы ничего не рисуете эти фонтом, а кнопку рисует обработчик QPushButton::paintEvent.


Название: Re: Перерисовка кнопок
Отправлено: antonkw от Февраль 27, 2014, 10:19
так ведь и использую внутри paintEvent`a, или нужно как-то по-другому применять?


Название: Re: Перерисовка кнопок
Отправлено: Swa от Февраль 27, 2014, 10:26
Вам нужно убрать QPushButton::paintEvent(paint); и рисовать свою кнопку вручную, используя методы QPainter : drawText, drawRect и т.д.


Название: Re: Перерисовка кнопок
Отправлено: antonkw от Февраль 27, 2014, 12:08
Вам нужно убрать QPushButton::paintEvent(paint); и рисовать свою кнопку вручную, используя методы QPainter : drawText, drawRect и т.д.
Немного не понимаю, где это реализовывать. Ведь нужно, насколько я понимаю, переопределить какой-то метод, рисующий сам виджет.


Название: Re: Перерисовка кнопок
Отправлено: NickSin от Март 12, 2014, 10:26
Вам нужно убрать QPushButton::paintEvent(paint); и рисовать свою кнопку вручную, используя методы QPainter : drawText, drawRect и т.д.
Немного не понимаю, где это реализовывать. Ведь нужно, насколько я понимаю, переопределить какой-то метод, рисующий сам виджет.

ну как я понял, говорят о то, что paintEvent  сам рисует тебе кнопку , поэтому изменить ее ты не сможешь. Для этого  в виджете, в котором ты ее выводишь, рисуй кнопку сам через QPainter и обрабатывай сигнал при наведении мышки на кнопку и перерисовывай ее в нужный тебе цвет.
Так я это все вижу


Название: Re: Перерисовка кнопок
Отправлено: Bepec от Март 12, 2014, 10:54
Всё то, что ты делаешь в paintEvent добавляется на экран, а QPushButton::paintEvent все перерисовывает поверх, основываясь на стиле и свойствах самой кнопки, а не ваших изменений.
Если хотите рисовать самому - придётся именно "рисовать самому" всё. Начиная от рамки, заканчивая текстом.

PS простейший способ - побаловаться с QSS. Сложный - нарисовать кнопку во всех состояниях и потом рисовать картинки в соответствии с состоянием.


Название: Re: Перерисовка кнопок
Отправлено: Igors от Март 12, 2014, 10:55
Из Вашего paintEvent нужно вызвать QPusjButton::paintEvent. Но для "кастомизации" наследование и переопределение paintEvent - не лучший вариант (а часто и худший). Лучше напр так:

Установить font - просто сделать объекту setFont
Подсветки - методы palette/setPalette (хотя можно и по-другому)
Эллипсовидная - ну не знаю, может придется через свой стиль

И еще: обычно после неск попыток "сделать красиво" энтузиазм иссякает, доходит что это работа большая и кропотливая  :)


Название: Re: Перерисовка кнопок
Отправлено: antonkw от Март 28, 2014, 19:03
Всем спасибо за помощь.
Решил отписаться, чтобы тема не превратилась в нерешенную (т.е. если вдруг кто-то будет страдать тем же, мог бы посмотреть, что к чему).
С помощью фона можно перерисовать весь фон виджета, что не вариант, если нужна кастомная форма.
С помощью стилей можно вставлять картинки, но нужно создавать свой класс и добавлять обработчик событий для изменения изображений:
Шаблон конструктора такого класса:
Код:
QPushButton1::QPushButton1(QString &text)
    {
 setText(text);
   this->setAttribute(Qt::WA_Hover);
   this->installEventFilter(this);
    }
bool QPushButton1::eventFilter(QObject * obj, QEvent * event)
{
    if (obj == this) {
        QEvent::Type type = event->type();
        if  (type == QEvent::HoverLeave) {
            this->setCursor(Qt::ArrowCursor);
        } else if (type == QEvent::HoverEnter) {
            this->setCursor(Qt::PointingHandCursor);
        }
    }
    return QWidget::eventFilter(obj, event);
}

Потом наткнулся на то, что и так есть функция, возвращающая 0/1 в зависимости от наведения мышки (я, напомню, только учусь, так что не нужно говорить, что это очевидно).

Перерисовал таким образом:
Код:
void QPushButton::paintEvent ( QPaintEvent * event )
{
this->setFixedSize(80,30);
QPainter painter(this);
QLinearGradient myGradient(0,0,150,30);
QPen myPen;
myPen.setBrush(Qt::black);
QRectF boundingRectangle(0,0,79,29);
QPainterPath myPath;
myPath.addEllipse(boundingRectangle);
myGradient.setColorAt (0.0,Qt::white);
painter.setPen(myPen);
if (this->underMouse()==0){
myGradient.setColorAt (1.0,Qt::yellow);
}else if (this->underMouse()==1){
myGradient.setColorAt (1.0,Qt::red);
};
painter.setBrush(myGradient);
painter.drawPath(myPath);
painter.setFont(QFont("Arial", 9));
painter.drawText(rect(), Qt::AlignCenter, text());
}