Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
dzx9
0 / 0 / 0
Регистрация: 22.08.2012
Сообщений: 11
1

Пропадает вкладка в предопределенном QTabBar

02.12.2012, 01:19. Просмотров 1538. Ответов 7
Метки нет (Все метки)

На данном форуме нашел код, позволяющий переворачивать вкладки горизонтально, когда они расположены слева в QTabWidget (т.е. положение West). Вот ссылка на сообщение:
[Решено] Повернуть заголовки вкладок QTabWidget
Как это выглядит:
Пропадает вкладка в предопределенном QTabBar


Но мне нужно было добавить ещё одну возможность, а именно посылать сигнал о текущем размере во время resize. Вот мой доработанный код:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#ifndef TABBAR_H
#define TABBAR_H
#include <QTabBar>
#include <QStylePainter>
#include <QStyleOptionTabV3>
#include <QPainter>
#include <QIcon>
#include <QString>
 
//---------------------------------------------------
//Добавлено, чтобы можно было извлечь QSize из QResizeEvent
#include <QResizeEvent>
//--------------------------------------------------- 
 
class TabBar : public QTabBar
{
 
//---------------------------------------------------
    //Добавляю сигнал
    Q_OBJECT 
signals:
    void resizeSignal(QSize event);
//---------------------------------------------------
 
public:
 
    explicit TabBar(QWidget* parent=0) : QTabBar(parent)
    {
        setIconSize(QSize(18, 18));
    }
 
protected:
    QSize tabSizeHint(int) const
    {
        return QSize(150, 30);
    }
 
//---------------------------------------------------
    //Добавил посылку сигнала во время resize
    void resizeEvent(QResizeEvent *event){
        emit resizeSignal(event->size());
    }
//---------------------------------------------------
 
    void paintEvent(QPaintEvent *)
    {
        QStylePainter p(this);
        for (int index = 0; index < count(); index++)
        {
            QStyleOptionTabV3 tab;
            initStyleOption(&tab, index);
            QIcon tempIcon = tab.icon;
            QString tempText = tab.text;
            tab.icon = QIcon();
            tab.text = QString();
            p.drawControl(QStyle::CE_TabBarTab, tab);
            QPainter painter;
            painter.begin(this);
            QRect tabrect = tabRect(index);
            tabrect.adjust(0, 8, 0, -8);
            painter.drawText(tabrect, Qt::AlignBottom | Qt::AlignHCenter, tempText);
            tempIcon.paint(&painter, 0, tabrect.top(), tab.iconSize.width(), tab.iconSize.height(), Qt::AlignTop | Qt::AlignHCenter);
            painter.end();
        }
    }
};
 
class TabWidget : public QTabWidget
{
public:
    explicit TabWidget(QWidget *parent = 0) : QTabWidget(parent)
    {
        setTabBar(new TabBar());
    }
};
 
#endif //TABBAR_H
Проблема наступает, когда я выбираю нижнюю вкладку, верхняя вклада пропадает, как будто её вытолкнули вверх (кстати, если выбрать верхнюю вкладку при помощи колесика мыши, все становится на свои места). И вообще, при смене вкладки они почему-то движутся по чу-чуть вверх. Вот как выглядит мой баг:
Пропадает вкладка в предопределенном QTabBar


Если закомментировать resizeEvent, то проблема пропадает.
Вопрос простой, как избавиться от бага?

Так же добавляю код, вызывающий ошибку
TabBar.zip
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.12.2012, 01:19
Ответы с готовыми решениями:

QTabBar, мигание иконки в определенном табе
Имеется QTabWidget в котором от 1 до N вкладок. Вкладки - это диалоги. Так вот когда приходит новое...

Как получить координаты определенной вкладки в QTabBar?
Я хочу получить QRect определенной вкладки в QTabBar, то есть её координаты и ширину с высотой....

Изменить background-color определенной вкладки QTabBar
Собственно имеется QTabWidget с нескольким количеством вкладок. Для выделенной вкладки применяется...

Пропадает вкладка Data Control
Добрый день , подскажите пожалуйста , почему при открытия формы модуля данных для изменения...

7
Чистый
Автор FAQ
2723 / 1419 / 89
Регистрация: 08.09.2011
Сообщений: 3,746
Записей в блоге: 1
02.12.2012, 01:21 2
о текущем размере чего?
скажите чего вы хотите добиться
0
dzx9
0 / 0 / 0
Регистрация: 22.08.2012
Сообщений: 11
02.12.2012, 02:52  [ТС] 3
Цитата Сообщение от Чистый Посмотреть сообщение
о текущем размере чего?
скажите чего вы хотите добиться
Хорошо. В начале не хотел посвящать во все детали. Но похоже, чтобы найти хорошее решение из ситуации лучше предоставить весь запутавшийся клубок.

Задача следующая:
1 - Сделать приложение, в котором основной элемент это QTabBar, только с вкладками, представленными выше.
2 - В первой вкладке сделать анимацию, загружающуюся из GIF файла + справа от этой анимации панель, которая то появляется, то исчезает. Дополнительная панель появляется когда пользователь щелкает мышкой по определенным участкам анимации. А пропадает, когда пользователь щелкает по кнопке Hide в этой дополнительной панельке.
3 - При смене размера окна, анимация должная заполнять все доступное пространство QTabBar, причем пропорции должны сохраняться, а в случае, если остается не занятая область, анимация должна центрироваться в ней.

Первую задачу я решил вашим методом, спасибо.
Вторую задачу решил написанием собственного класса, унаследованного от QLabel и загрузил анимацию из ресурсов при помощи QMovie. Назвал этот класс ImageClick.
А вот с третьей задачей у меня тридцать три несчастья. Если бы у меня было простое изображение, а не анимация, тогда можно при вызове resize менять размеры pixmap с помощью, например, метода scaledToWidth, который и масштабирует и сохраняет пропорции. Но у меня то, нет pixmap'а, у меня QMovie.
Хорошо, попробовал переопределить resizeEvent для ImageClick. В котором вызывал resize(), указывая подкорректированные размеры с нужными мне пропорциями. Но тут возникло две проблемы
- ImageClick стал занимать исключительно левый верхний угол, а не центр, как ему положено
- элементы с правой и левой панелью не правильно взаимодействовали друг с другом, то накладывались, то один другой вытеснял
Тогда я решил задавать не resize(), а setMaximumSize(), эти две проблемы исчезли, зато код потерял в своей эстетичности, так как масштабирование приходится обрабатывать не в песочнице ImageClick, а гонять события из одного класса в другой. А так же появилась ошибка пропадания вкладки, с которой я и начал.
Выкладываю код, который пояснит ситуацию наглядно.
TabBar2.zip
0
KeyGen
386 / 293 / 21
Регистрация: 07.08.2011
Сообщений: 790
Записей в блоге: 1
02.12.2012, 02:59 4
Наследуешь от QLabel... А что если установить свойство которое изображение растянет?
C++ (Qt)
1
QLabel::setScaledContents(bool);
Добавлено через 1 минуту
Или Qml поюзать...
0
dzx9
0 / 0 / 0
Регистрация: 22.08.2012
Сообщений: 11
02.12.2012, 15:15  [ТС] 5
Цитата Сообщение от KeyGen Посмотреть сообщение
Наследуешь от QLabel... А что если установить свойство которое изображение растянет?
C++ (Qt)
1
QLabel::setScaledContents(bool);
Добавлено через 1 минуту
Или Qml поюзать...
Забыл упомянуть, что через setScaledContents(true) и растягиваю изображение, так как без этого resize() или setMaximumSize() не масштабируют, а просто вырезают кусок нужного размера из изображения. Но у setScaledContents(true) есть неприятное свойство, он не сохраняет пропорции. Именно для этого я и делаю все нагромождения, чтобы пропорции сохранились.

А вот QML никогда не использовал. Поэтому если подскажете, как через него решить проблему, буду благодарен.
0
KeyGen
386 / 293 / 21
Регистрация: 07.08.2011
Сообщений: 790
Записей в блоге: 1
02.12.2012, 15:54 6
Что бы оно не растягивалось самому писать надо на С++. В QWidget есть virtual void resizeEvent (QResizeEvent * event); от него и отталкиваться. Обрабатывать изображение при изменении и затем вставлять в QLabel. (QLabel наследует методы QWidget). На Qml другая история, С++ проще ИХМО.
0
dzx9
0 / 0 / 0
Регистрация: 22.08.2012
Сообщений: 11
02.12.2012, 16:37  [ТС] 7
Цитата Сообщение от KeyGen Посмотреть сообщение
Что бы оно не растягивалось самому писать надо на С++. В QWidget есть virtual void resizeEvent (QResizeEvent * event); от него и отталкиваться. Обрабатывать изображение при изменении и затем вставлять в QLabel. (QLabel наследует методы QWidget). На Qml другая история, С++ проще ИХМО.
По-моему вы меня немного не поняли.

Цитата Сообщение от dzx9 Посмотреть сообщение
Хорошо, попробовал переопределить resizeEvent для ImageClick. В котором вызывал resize(), указывая подкорректированные размеры с нужными мне пропорциями.
Я так и сделал, но столкнулся с проблемами описанными выше.
Кстати, сейчас попробовал убрать resizeEvent из TabBar, а вместо этого добавил resizeEvent в класс главного окна, и при вызове метода MainWindow::resizeEvent посылаю TabBar'у сигнал, который в свою очередь отправит сигнал ImageClick'у с указанием нужного размера.
То есть картина выглядит следующим образом:
MainWindow -> TabBar -> ImageClick
В итоге проблема с вытеснением верхней вкладки пропала, зато при первоначальном запуске приложения, анимация в ImageClick не появляется до тех пор, пока не изменишь размер главного окна, то есть, пока не вызовется MainWindow::resizeEvent.
Ох, это не было бы так грустно, если бы не смешно.
Вкладываю текущую версию изменений, чтобы наглядно продемонстрировать проблему, может кто-нибудь захочет посмотреть. Я Специально сделал этот тестовый проект, из которого выкинул все лишнее и добавил исключительно код, связанный с описанной проблемой.
TabBar3.zip
0
dzx9
0 / 0 / 0
Регистрация: 22.08.2012
Сообщений: 11
03.12.2012, 11:49  [ТС] 8
В продолжение темы "костылей", сразу после MainWindow::show() вызываю MainWindow::resize(), что решает проблему с первоначальным не отображением анимации. Закон Кирхгофа соблюден - количество входящих багов соответствует выходящему количеству заплаток на них. Но все же, если кто-то может подсказать мне как лучше было бы построить архитектуру этого приложения, буду очень благодарен за наставничество и указание пути истинного.
0
03.12.2012, 11:49
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.12.2012, 11:49

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Программа, которая проверяет находится ли число в заранее предопределенном массиве
Нужна программа которая проверяет находится ли число в заранее предопределенном массиве

Tabhost, TabWidget; можно ли создать систему вкладка-вкладка
Подскажите пожалуйста можно ли создать систему вкладка-вкладка?? по сути при нажатие вкладки...

Выкидывает из аськи, пропадает соединение со стимом, полностью пропадает инет
У меня проблемка такая с соеденением к интернету, не знаю что делать... Вообщем комп работает...

Пропадает общий доступ, когда пропадает интернет
На нашем предприятии локальная сеть, имеющая организацию &quot;рабочая группа&quot;. В кабинете используется...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.