Нарисуйте QPushButton с помощью QLinearGradient - PullRequest
0 голосов
/ 22 января 2019

Я пытаюсь использовать QLinearGradient, чтобы нарисовать QPushButton, но безуспешно. Я нашел примеры того, как покрасить его сплошным цветом. Но мне не удалось найти примеры цветового градиента. Более того, мой подход не сработал.

Вот мой полный пример, где кнопка сплошного цвета работает, а кнопка линейного градиента - нет:

#include <QApplication>
#include <QGridLayout>
#include <QLinearGradient>
#include <QPalette>
#include <QPushButton>

int main(int argc, char** argv)
{
  QApplication app(argc, argv);

  // Create layout
  QGridLayout* layout = new QGridLayout;

  // Create first button
  QPushButton* button_1 = new QPushButton();
  layout->addWidget(button_1, 0, 0);
  QPalette palette_1 = button_1->palette();
  palette_1.setColor(QPalette::Button, Qt::red);
  button_1->setPalette(palette_1);
  button_1->update();

  // Create second button
  QPushButton* button_2 = new QPushButton();
  layout->addWidget(button_2, 0, 1);
  QLinearGradient gradient_button(0, 0, button_2->width(), 0);
  gradient_button.setColorAt(0, Qt::white);
  gradient_button.setColorAt(1, Qt::black);
  QPalette palette_2 = button_2->palette();
  QBrush brush(gradient_button);
  palette_2.setBrush(QPalette::Button, brush);
  button_2->setPalette(palette_2);
  button_2->update();

  // Create widget
  QWidget* widget = new QWidget;
  widget->setLayout(layout);
  widget->resize(300, 50);

  /// Show
  widget->show();

  // Run
  return app.exec();
}

Есть идеи, что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Ваш градиент настроен на переход от <0, 0> до <button_2->width(), 0>, но в момент создания градиента button_2 не включен ни в один макет: его ширина будет вычислена, когда родительский виджет (следовательно, макет, где кнопка) изменена. Если вы попытаетесь зафиксировать ширину, вы увидите, что градиент работает как положено.

QPushButton* button_2 = new QPushButton();
button_2->setFixedWidth(100);

Вы можете использовать фильтр событий, чтобы следить за изменением размера и корректировать градиент соответственно:

class ButtonResizeWatcher : public QObject {
protected:
  virtual bool eventFilter(QObject* o, QEvent* e) override {
    if (e->type() == QEvent::Resize) {
      auto button = qobject_cast<QPushButton*>(o);

      QLinearGradient gradient_button(0, 0, button->width(), 0);
      gradient_button.setColorAt(0, Qt::white);
      gradient_button.setColorAt(1, Qt::red);

      auto palette = button->palette();
      palette.setBrush(QPalette::Button, QBrush(gradient_button));
      button->setPalette(palette);
    }

    return QObject::eventFilter(o, e);
  }
};

Использование:

ButtonResizeWatcher resize_watcher;
button_2->installEventFilter(&resize_watcher);

Полный код можно найти в GitHub .

Другим вариантом, как отмечено в другом ответе, будет использование таблицы стилей (qlineargradient). От вас зависит, нужен ли вам дополнительный контроль над кистью, такой как «показывать градиент, но только до достижения определенной ширины». Кроме того, примите во внимание, что таблицы стилей обычно конфликтуют с другими QStyle (если используются).

0 голосов
/ 22 января 2019

Безуспешно, я попробовал это с QPalette и сделал успешно, используя setStyleSheet:

QPushButton* button = new QPushButton();
QString linearGradient = QString("qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));");

button->setStyleSheet(QString("background-color: %1").arg(linearGradient));

Кроме того, мы можем использовать QString::arg(...) для установки различных цветов и точек для градиента.

Надеюсь, это поможет вам и простите за глупый комментарий ранее)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...