Russian Qt Forum
Ноябрь 24, 2024, 23:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: 4.3.2: нужна помощь c QTabBar  (Прочитано 6638 раз)
ритт
Гость
« : Ноябрь 25, 2007, 13:55 »

весь мозг оно мне уже прогрызло...три месяца откладываю "на потом"

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

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

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

кто-нибудь сталкивался? кто-нибудь имеет готовое решение? Улыбающийся
Записан
ритт
Гость
« Ответ #1 : Ноябрь 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);
}

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

может, кто-нибудь подскажет альтернативу? или опять спамить троллей?
Записан
vaprele07
Гость
« Ответ #2 : Ноябрь 25, 2007, 16:07 »

resizeEvent()
Записан
ритт
Гость
« Ответ #3 : Ноябрь 25, 2007, 16:14 »

дык, один хрен! resizeEvent - один из ченджИвентов, значит, layoutTabs() вызовётся тем же путём, но ещё и все детишки среагируют...
Записан
vaprele07
Гость
« Ответ #4 : Ноябрь 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;
};
Записан
ритт
Гость
« Ответ #5 : Ноябрь 26, 2007, 11:56 »

вапреле, спасибо
почти так и делаю, только ченджИвент зову не из рисовалки, а на изменение текущегоИндекса
всё-равно это тот же костыль и, видимо, иначе сейчас не получится
Записан
ритт
Гость
« Ответ #6 : Ноябрь 26, 2007, 12:35 »

хмм...ещё один вариант: вместо ченджИвента звать QTabBar::setIconSize(QTabBar::iconSize()) - тогда иконки не меняются, но шедулится пересчёт геометрий и вызывается отрисовка

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

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


вапреле, при ближайшем рассмотрении выходит, что костыль не тот же
если найдётся время, протестируй свой код, т.к. в виду одного маленького затыка мой старый вариант был много лучше
« Последнее редактирование: Ноябрь 28, 2007, 03:12 от xep » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.053 секунд. Запросов: 21.