Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ресайз родителя обрабатывать в ребенке, Qwidget, QEvent 
:(
    Опции темы
becks
Дата 26.10.2012, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 6.7.2010

Репутация: нет
Всего: нет



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

И вот главная проблема, что при ресайзе родителя, от него остается скролл на старом месте. Предок (покрывало) ресайзится нормально. 

Покрывалу назначил eventFilter:

Код

bool Glass::eventFilter(QObject *object, QEvent* event)
{
    if(object != this && object != m_parent)
        return false;

    if(event->type() == QEvent::Resize)
    {
        QWidget *w = qobject_cast<QWidget *>(object);
        m_glass->resize(m_glass->parentWidget()->size());
        w->repaint();
        m_glass->move(0, 0);
        positioning();
        return true;
    }
    m_glass->setFocus();
    return false;
}


для родителя делаю:
Код

ui->documentTabs->currentWidget()->installEventFilter(glass);


Если свернуть и развернуть приложение, то скролл встает на правильное место.

Это сообщение отредактировал(а) becks - 26.10.2012, 16:11
PM MAIL   Вверх
hawk3500
Дата 28.10.2012, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 246
Регистрация: 6.2.2009

Репутация: нет
Всего: 2



А может просто сделать hide для родительского виджета?
--------------------
воин dzen'a
PM MAIL   Вверх
becks
Дата 29.10.2012, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 6.7.2010

Репутация: нет
Всего: нет



Цитата

А может просто сделать hide для родительского виджета? 


Чтобы было нагляднее вот картинка:

Растянутый родительский виджет. Скролл остался на месте.


Тут одна вкладочка закрыта от редактирования пока идет какой-то процесс, остальные пользователь может редактировать и в том числе и изменять размер мэйнвиндоуса. Я полагаю hide() тут не поможет.

Это сообщение отредактировал(а) becks - 29.10.2012, 10:25
PM MAIL   Вверх
becks
Дата 5.11.2012, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 6.7.2010

Репутация: нет
Всего: нет



Собственно, все еще не могу понять почему не перерисовывается скролл, задачу не решил. Прошу помощи.
PM MAIL   Вверх
loneybibi
Дата 8.11.2012, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 28.5.2010
Где: Донецк (Украина)

Репутация: 3
Всего: 3



Цитата(becks @ 26.10.2012,  14:59)
Добрый день, коллеги! Вопрос такой, хочу в программе в моменты длительных вычислений накрывать некоторый виджет другим виджетом с красивыми эффектами, дабы запретить редактирование. В качестве виджета родителя может выступать практически любой виджет от главной формы до закладок в табвиджете. 

И вот главная проблема, что при ресайзе родителя, от него остается скролл на старом месте. Предок (покрывало) ресайзится нормально. 

Покрывалу назначил eventFilter:

Код

bool Glass::eventFilter(QObject *object, QEvent* event)
{
    if(object != this && object != m_parent)
        return false;

    if(event->type() == QEvent::Resize)
    {
        QWidget *w = qobject_cast<QWidget *>(object);
        m_glass->resize(m_glass->parentWidget()->size());
        w->repaint();
        m_glass->move(0, 0);
        positioning();
        return true;
    }
    m_glass->setFocus();
    return false;
}


для родителя делаю:
Код

ui->documentTabs->currentWidget()->installEventFilter(glass);


Если свернуть и развернуть приложение, то скролл встает на правильное место.

Я так понял что positioning() это и есть длительная операция.
Так как она выполняется внутри виджета то естественно он подвиснет и отрисовка GUI тоже будет тупить.
Попробуйте вместо метода repaint() вызвать метод update() и не до а после метода move(), насколько я помню он сам вызовет метод repaint() как надо.

Вообще обычно всегда при длительных операция GUI подвисает.

Такие объемные функции надо выносить в отдельный поток, почитайте про QThread.

Конечно есть другой вариант! Сделать псевдо-поток но у этого способа есть некоторые нюансы!
Хотя я думаю вам может подойди. Почитайте эту статью:
http://www.opennet.ru/docs/RUS/qt3_prog/x4064.html
Как это делается показал в коде, но опять же повторюсь что лучше использовать QThread, так и GUI подвисать не будет и отрисовка будет нормальной.

Код

bool Glass::eventFilter(QObject *object, QEvent* event)
{
    if(object != this && object != m_parent)
        return false;
    if(event->type() == QEvent::Resize)
    {
        QWidget *w = qobject_cast<QWidget *>(object);
        m_glass->resize(m_glass->parentWidget()->size());
        m_glass->move(0, 0);

        w->update(); //<<<<<<<<<<<

        qApp->processEvents(); // <<<<<<< Псевдо-поток

        positioning();

        return true;
    }
    m_glass->setFocus();
    return false;
}



--------------------
Red Hat Fedora 17
Qt 4.8.1 (x64), GCC 4.4.3,
G++ 4.4.3, QtCreator 2.4.1
PM MAIL ICQ   Вверх
becks
Дата 8.11.2012, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 6.7.2010

Репутация: нет
Всего: нет



Видимо плохо всё объяснил, сейчас попытаюсь более детально.

Есть некоторое приложение, по внешнему виду очень напоминающее Notepad++, т.е. существует центральный QTabWidget, и в нем несколько вкладок, каждая такая вкладка представляет собой QGraphicsView на нем я рисую граф и изначально у него есть скролл. Вот, и так как некоторые задачи обработки графа занимают продолжительное время, вкладку на которой расположен граф я хочу на это время накрывать объектом-покрывалом Glass. Другие вкладки в это время должны быть потенциально доступны (в принципе так оно сейчас и есть).

Сейчас я пока не делаю никаких нагруженных задач, а просто по нажатию на некоторую кнопку в MainWindow  накрываю объектом-покрывалом Glass открытую вкладку:

Код

void MainWindow::changeWorkingMode()
{

    ....
    Glass *glass = new Glass("Производится сохранение настроек базовых объектов!\n"
                             "Данная операция может занять некоторое время.\n");
    ui->documentTabs->currentWidget()->installEventFilter(glass);
    glass->setAnimationDuration(200);
    glass->init(ui->documentTabs->currentWidget());
}


В этом коде вроде должно быть все понятно. 

Хотя теперь у меня возникают сомнения о правильности вызова installEventFilter?

Вот определение класса Glass:

Код

class Glass : public QObject
{
    Q_OBJECT
public:
    explicit Glass(QString message = "", int stepCount = 0);
    virtual ~Glass();
...
    void setAnimationDuration(int duration);
    void init(QWidget *parent); // виджет-родитель, который накрываем
    void hideAndDelete();

protected:

    bool eventFilter(QObject* object, QEvent* event);

private:
    QLabel* m_glass;
    QLabel* m_infoText;
    QProgressBar *m_progressBar;

    QWidget *m_parent;
};


QLabel* m_glass - растягивается по родительскому виджету.



Это сообщение отредактировал(а) becks - 8.11.2012, 22:10
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0460 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.