Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: ритт от Ноябрь 25, 2007, 13:55



Название: 4.3.2: нужна помощь c QTabBar
Отправлено: ритт от Ноябрь 25, 2007, 13:55
весь мозг оно мне уже прогрызло...три месяца откладываю "на потом"

задача: рисовать хнопочку закрытия на текущей открытой закладке (как в Опере, например), причём, выделять под эту хнопочку дополнительных 20-25 пикселей в ширину - чтобы текст не перекрывала

как делаю: отнаследовался от QTabBar и перегрузил virtual QSize tabSizeHint(int index) const, где добавляю эти несчастные пиксели (пэинтИвент пока не перегружаю, т.к. размеры берутся из табСайзХинта).

исходя из прочитанного в сырцах, уверен, что при каждом событии, связанном с изменениями размера, минимальный/максимальный/нормальный размеры пересчитываются и вызывается апдейт.
но на деле адекватно отрисовывается только первая закладка, и только до тех пор, пока не добавлю ещё хотя бы одну закладку

кто-нибудь сталкивался? кто-нибудь имеет готовое решение? :)


Название: Re: 4.3.2: нужна помощь c QTabBar
Отправлено: ритт от Ноябрь 25, 2007, 14:46
бууууэээээ...

конечно, может сказываться тот факт, что я двое суток от монитора почти не отползаю, но может быть, что просто тролли жгут!

чтобы пересчитать размеры табов, необходимо вызвать метод layoutTabs() из приватной секции, который тролли вызывают из приватного refresh(), который вызывается на всяческие изменения размера/стиля (добавление/удаление табов, установка текста/иконки табе и глобальный чендж). а как-нибудь насильно взять и обновить размеры _нельзя_

но разглядел такой код:
Код:
void QTabBar::changeEvent(QEvent *e)
{
    Q_D(QTabBar);
    if (e->type() == QEvent::StyleChange) {
        d->elideMode = Qt::TextElideMode(style()->styleHint(QStyle::SH_TabBar_ElideMode, 0, this));
        d->useScrollButtons = !style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, this);
    }
    d->refresh();
    QWidget::changeEvent(e);
}

и пока что выкрутился так:
Код:
connect(this, SIGNAL(currentChanged(int)), this, SLOT(slot_setCurrentIndex(int)));
//...
void TabWidget::slot_setCurrentIndex(int index)
{
Q_UNUSED(index)

QEvent event(QEvent::ModifiedChange);
QApplication::sendEvent(tabBar(), &event);
}

это какое-то /* вырезано цензурой */ !

может, кто-нибудь подскажет альтернативу? или опять спамить троллей?


Название: Re: 4.3.2: нужна помощь c QTabBar
Отправлено: vaprele07 от Ноябрь 25, 2007, 16:07
resizeEvent()


Название: Re: 4.3.2: нужна помощь c QTabBar
Отправлено: ритт от Ноябрь 25, 2007, 16:14
дык, один хрен! resizeEvent - один из ченджИвентов, значит, layoutTabs() вызовётся тем же путём, но ещё и все детишки среагируют...


Название: Re: 4.3.2: нужна помощь c QTabBar
Отправлено: vaprele07 от Ноябрь 26, 2007, 06:16
Код:
class MyTabBar : public QTabBar
{
  Q_OBJECT
  public:
    MyTabBar (QWidget * parent = 0) : QTabBar(parent)
    {
      button = QRect();
      curItemRect = QRect();
    }
  protected: 
    void paintEvent(QPaintEvent *e)
    {
      if (e->region().contains(curItemRect)){
        const QSize s = size();
        QResizeEvent *re = new QResizeEvent(s, s);
        resizeEvent(re);
        delete re;
      }
     
      QTabBar::paintEvent(e);
     
      if (e->region().contains(curItemRect))
        drawButton(button);
    }
    void resizeEvent(QResizeEvent *e)
    {   
      QTabBar::resizeEvent(e);
      curItemRect = tabRect(currentIndex());
      button = QRect(curItemRect.right() - 35, curItemRect.top(), 35, curItemRect.height());
    }
    QSize tabSizeHint(int index) const
    {
      QSize size = QTabBar::tabSizeHint(index);
      if (index == currentIndex()){
        size.setWidth(size.width() + 40);
      }
      return size;
    }
    virtual void drawButton(const QRect &rect)
    {
      QPainter painter(this);
           
      painter.drawText(rect,
        Qt::AlignHCenter | Qt::AlignVCenter, QString("(X)"));
    }
  private:
    QRect button;
    QRect curItemRect;
};


Название: Re: 4.3.2: нужна помощь c QTabBar
Отправлено: ритт от Ноябрь 26, 2007, 11:56
вапреле, спасибо
почти так и делаю, только ченджИвент зову не из рисовалки, а на изменение текущегоИндекса
всё-равно это тот же костыль и, видимо, иначе сейчас не получится


Название: Re: 4.3.2: нужна помощь c QTabBar
Отправлено: ритт от Ноябрь 26, 2007, 12:35
хмм...ещё один вариант: вместо ченджИвента звать QTabBar::setIconSize(QTabBar::iconSize()) - тогда иконки не меняются, но шедулится пересчёт геометрий и вызывается отрисовка

/* дописано */

хотел удалить мессаг, но вдруг кому пригодится. если звать QTabBar::setIconSize(QTabBar::iconSize()), эффект будет как и в варианте выше, но сырцы говорят, что после установки setIconSize iconSize больше не будет читаться из стиля (PM_TabBarIconSize) при смене оного...
так что, сам себе "режектед"


вапреле, при ближайшем рассмотрении выходит, что костыль не тот же
если найдётся время, протестируй свой код, т.к. в виду одного маленького затыка мой старый вариант был много лучше