Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: xintrea от Январь 23, 2009, 00:00



Название: Маленькая кнопка закрытия. Рисовать крестик самому, или есть какой-то стиль?
Отправлено: xintrea от Январь 23, 2009, 00:00
Здравствуйте!


Нужно мне сделать виджет (который будет встраиваться рядом с обычными виджетами), но у него должна быть маленькая кнопка закрытия. Поковырялся в поиске, нашел только рекомендации что надо использовать QToolButton и самому нарисовать крестик. Это сделать конечно не проблема, но интересует более правильное решение.

Можно ли как-то указать стиль для кнопочки, что это "маленькая кнопка закрытия". Или может, можно для виджета указать что он содержит только кнопку закрытия, и эта кнопка маленькая? В примере examples/widgets/windowflags подходящего окошка сгенерировать не смог. Покурил флаг Qt::Tool, но он работает вроде как только для окна, создавая плоский заголовок и маленькую кнопку.

Кто что скажет?


Название: Re: Маленькая кнопка закрытия. Рисовать крестик самому, или есть какой-то стиль?
Отправлено: ритт от Январь 23, 2009, 03:50
кнопка закрытия - которая для закрытия окна? если да, из кутэ нет доступа к декорациям WM
я для такой же цели делал примерно так:

Код
C
class CloseButton : public QAbstractButton
{
Q_OBJECT
 
public:
CloseButton(QWidget* parent = 0);
 
QSize sizeHint() const;
inline QSize minimumSizeHint() const
{ return sizeHint(); }
 
void changeEvent(QEvent* event);
void paintEvent(QPaintEvent* event);
};
 
CloseButton::CloseButton(QWidget* parent) : QAbstractButton(parent)
{
setFocusPolicy(Qt::NoFocus);
setCursor(Qt::ArrowCursor);
setToolTip(tr("Close"));
 
QStyleOptionDockWidget opt;
setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt));
 
resize(sizeHint());
}
 
QSize CloseButton::sizeHint() const
{
return QSize(14, 14);
}
 
void CloseButton::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event)
 
QPainter painter(this);
QStyleOption opt;
opt.init(this);
opt.state |= QStyle::State_AutoRaise;
if(isEnabled() && underMouse() && !isChecked() && !isDown())
opt.state |= QStyle::State_Raised;
if(isEnabled())
opt.state |= QStyle::State_Enabled;
if(isChecked())
opt.state |= QStyle::State_On;
if(isDown())
opt.state |= QStyle::State_Sunken;
opt.state |= QStyle::State_Selected;
 
 
QSize size = sizeHint();
QIcon::Mode mode = opt.state & QStyle::State_Enabled ?
(opt.state & QStyle::State_Raised ?
QIcon::Active
: QIcon::Normal)
: QIcon::Disabled;
if(!(opt.state & QStyle::State_Raised) && !(opt.state & QStyle::State_Sunken)
&& !(opt.state & QStyle::State_Selected))
mode = QIcon::Disabled;
QIcon::State state = opt.state & QStyle::State_On ? QIcon::On : QIcon::Off;
QPixmap pixmap = icon().pixmap(size, mode, state);
style()->drawItemPixmap(&painter, opt.rect, Qt::AlignCenter, pixmap);
}
 
void CloseButton::changeEvent(QEvent* event)
{
QAbstractButton::changeEvent(event);
 
if(event->type() == QEvent::StyleChange)
{
QStyleOptionDockWidget opt;
setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt));
}
}
 


Название: Re: Маленькая кнопка закрытия. Рисовать крестик самому, или есть какой-то стиль?
Отправлено: xintrea от Январь 24, 2009, 21:36
Решил сделать так. Мне подходит QToolButton, только надо его настроить.

Установить иконку с крестиком я могу так

Код:
closebutton=new QToolButton();
closebutton->setIcon(qApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));

После этого я хочу изменить размер кнопки. Ну например, сделать ее в два раза меньше. А чтобы это сделать, надо знать размер кнопки. Я пытаюсь сделать вот так

Код:
int w=closebutton->geometry().width();
int h=closebutton->geometry().height();
qDebug() << "width " << w << " height " << h;

И вместо нормальных чисел получаю 640x480. Что это за цифири? Как узнать размер кнопки?


Название: Re: Маленькая кнопка закрытия. Рисовать крестик самому, или есть какой-то стиль?
Отправлено: xintrea от Январь 26, 2009, 00:32
Апну тему.

Пока сделал задание абсолютных размеров кнопки в точках. Но хотелось бы высчитывать относительные.


Название: Re: Маленькая кнопка закрытия. Рисовать крестик самому, или есть какой-то стиль?
Отправлено: BRE от Январь 26, 2009, 08:58
QSize sz = closebutton->sizeHint();  ???


Название: Re: Маленькая кнопка закрытия. Рисовать крестик самому, или есть какой-то стиль?
Отправлено: xintrea от Январь 26, 2009, 16:12
QSize sz = closebutton->sizeHint();  ???

Не, тоже не то. Неизменённая кнопка на экране имеет размер 27x26 пикселей (замерил). А этот метод возвращает размер 9x8.


Название: Re: Маленькая кнопка закрытия. Рисовать крестик самому, или есть какой-то стиль?
Отправлено: xintrea от Январь 27, 2009, 17:23
Посмотрел в QtDesigner как задается размер. Так и есть, используются свойства geometry.width и geometry.height. Сделал тестовый пример - та же самая проблема, geometry().width() и geometry().height() возвращат "магические" числа 640x480.


UPD! Нашел проблему. Оказывается, это действительно магические числа, выставляемые вначале для вновь соданных виджетов. И пока виджет не будет отрисован на экран, его настоящий размер узнать вроде как нельзя. Даже после размещения в layout, настоящий размер виджета неизвестен.

Но обнаружил один трюк. Можно после создания виджета вызвать метод setVisible(true), т.к. обычно, всеравно виджет будет виден в нужном месте в лайоуте. После вызова метода setVisible(true), методы geometry().width() и geometry().height() начинают возвращать правильные значения, как минимум для "нерастяжимых" объектов.


Название: Re: Маленькая кнопка закрытия. Рисовать крестик самому, или есть какой-то стиль?
Отправлено: xintrea от Январь 27, 2009, 18:07
И еще, как выяснилось, для получения человеческих чисел, обязательно нужно для кнопки указывать родителя. В разных ситуациях код

Код:
 closebutton=new QToolButton();
 closebutton->setVisible(true);
 int w=closebutton->geometry().width();
 int h=closebutton->geometry().height();
 qDebug() << "width " << w << " height " << h;

может позвращать некорректные значения. Для корректных значений нужно использовать конструктор с параметром

Код:
closebutton=new QToolButton(this);

тогда геометрия будет возвращаться правильно.