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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QDialog и затенение окна  (Прочитано 6419 раз)
Termit
Самовар
**
Offline Offline

Сообщений: 144



Просмотр профиля WWW
« : Июль 31, 2011, 20:51 »

Добрый день.

Хочу реализовать затенение главного окна приложения при открытии модального диалога. Не получается ничего нормального.
То ничего не происходит, то работает крайне медленно :-(

Хотелось бы чтобы работало без лишнего наследования виджетов.

Поиск по google и по форуму понимания ситуации не добавил.

Делал так. Вроде на форуме было...
Код
C++ (Qt)
QPixmap px = QPixmap::grabWidget( this );
QPainter p( &px );
p.setBrush( QColor( 0, 0, 0, 100 ) ); // highligh a bit
p.setPen( Qt::NoPen );
p.drawRect( px.rect() );
p.end();
 
Ничего не происходит...

Делал свой QGraphicsEffect
в методе draw
Код
C++ (Qt)
painter->fillRect(boundingRect(), QColor( 0, 0, 0, 100 ));
 
Тормозит со страшной силой. И похоже, что вызывается для каждого объекта на форме

Есть ли у кого решение? В какую сторону копать?
Записан

Человеческая глупость дает представление о бесконечности
(с) Иоанна Хмелевская
SimpleSunny
Гость
« Ответ #1 : Июль 31, 2011, 21:20 »

Может попробовать так

Код
C++ (Qt)
setEnabled(false);
//по желанию qApp->processEvents();
dlg.exec();
setEnabled(true);
Записан
Termit
Самовар
**
Offline Offline

Сообщений: 144



Просмотр профиля WWW
« Ответ #2 : Июль 31, 2011, 21:23 »

Может попробовать так

Код
C++ (Qt)
setEnabled(false);
//по желанию qApp->processEvents();
dlg.exec();
setEnabled(true);

Нет, ну это же не затемнение...
Записан

Человеческая глупость дает представление о бесконечности
(с) Иоанна Хмелевская
Termit
Самовар
**
Offline Offline

Сообщений: 144



Просмотр профиля WWW
« Ответ #3 : Август 01, 2011, 00:12 »

После того как добавил строку
Код
C++ (Qt)
painter->setRenderHint(QPainter::Antialiasing);
painter->fillRect(boundingRect(), QColor( 0, 0, 0, 100 ));
 
вдруг стало быстро работать...
Записан

Человеческая глупость дает представление о бесконечности
(с) Иоанна Хмелевская
climber
Гость
« Ответ #4 : Август 01, 2011, 11:09 »

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

Вот как реализовано у меня
Код:

class Glass : public QDialog
{
    Q_OBJECT

public:
  Glass(QWidget *parent = 0);
  ~Glass();
  QBrush *mask;
  QLabel *informationText;
  QLabel *glass;
  QLabel *animationContainer;
  QLabel *progress;
  QMovie *defaultMovie;
  int install; // 1 - положить стекло 0 - убрать
  void installGlass(QWidget *w);
public slots:
  void removeGlass();
  void setProgress(double p);
};

Glass::Glass(QWidget *parent):
    QDialog(parent)
{

    install = 0;
    QGraphicsOpacityEffect *opacityEffect = new QGraphicsOpacityEffect(parent);
    const QColor& color = QColor(111, 111, 100);

    mask = new QBrush();
    mask->setColor(color);
    mask->setStyle(Qt::SolidPattern);
    qreal opacity = 0.7;

    opacityEffect->setOpacityMask(*mask);
    opacityEffect->setOpacity(opacity);

    glass = new QLabel(parent);
    glass->setGraphicsEffect(opacityEffect);
    glass->setVisible(false);

    informationText = new QLabel(parent);
    informationText->setVisible(false);
    informationText->setText(trUtf8("Подождите\n Выполняется отбор данных..."));
    QFont font;
    font.setPointSize(12);
    font.setWeight(QFont::Bold);
    informationText->setFont(font);
    informationText->setAlignment(Qt::AlignHCenter);

    QPalette pal(informationText->palette());
    pal.setColor(QPalette::Foreground, QColor("white"));

    informationText->setPalette(pal);

    animationContainer = new QLabel(parent);
    animationContainer->setVisible(false);
    defaultMovie = new QMovie("/pictures/loading51.gif", QByteArray(), animationContainer);
    animationContainer->setMovie(defaultMovie);
    defaultMovie->start();

    progress = new QLabel(parent);
    progress->setVisible(false);
    progress->setPalette(pal);
    progress->setAlignment(Qt::AlignHCenter);

}

Glass::~Glass()
{
  delete progress;
  delete defaultMovie;
  delete animationContainer;
  delete informationText;
  delete glass;
  delete mask;
}

void Glass::installGlass(QWidget *w)
{
  install = 1;
  glass->setVisible(true);
  informationText->setVisible(true);
  animationContainer->setVisible(true);
  progress->setVisible(true);

  progress->setGeometry(w->size().width()/2 - 17,w->size().height()/2 - 80,30,15);
  animationContainer->setGeometry(w->size().width()/2 - 65,w->size().height()/2 - 150,300,150);
  informationText->setGeometry(w->size().width()/2 - 150,w->size().height()/2,300,150);
  glass->setGeometry(0,0,w->size().width(),w->size().height());
}

void Glass::removeGlass()
{
  install = 0;
  glass->setVisible(false);
  informationText->setVisible(false);
  animationContainer->setVisible(false);
  progress->setVisible(false);
}

void Glass::setProgress(double p)
{
  QString str_persent;
  str_persent.setNum((int)p);

  progress->setText(str_persent);
}

Работает шустро.
Записан
Termit
Самовар
**
Offline Offline

Сообщений: 144



Просмотр профиля WWW
« Ответ #5 : Август 01, 2011, 17:51 »

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

Спасибо, как вернусь из командировки помедитирую.
По результатам отпишусь.
Записан

Человеческая глупость дает представление о бесконечности
(с) Иоанна Хмелевская
trot
Гость
« Ответ #6 : Август 01, 2011, 20:32 »

Создаешь QWidget, распахиваешь его на все свое окно, устанавливаешь прозрачность, а потом вызываешь свой модальный диалог. После закрытия диалога, уничтожаешь виджет. Вот и все.
Записан
Termit
Самовар
**
Offline Offline

Сообщений: 144



Просмотр профиля WWW
« Ответ #7 : Август 03, 2011, 18:52 »

Вот как реализовано у меня

Спасибо, получилось то, что хотел...

to All:

Проясните такую ситуацию:
для простоты изложения вложил маленький проект, который на коленке собрал из QGraphicsEffect и решения climber.

Так вот, если применить напрямую (key 1) эффект на форму где что-то изменяется, то эффект применяется много раз. В коде есть закомментированный костыль.

Собственно почему так происходит?
Записан

Человеческая глупость дает представление о бесконечности
(с) Иоанна Хмелевская
climber
Гость
« Ответ #8 : Август 04, 2011, 10:56 »

Как мне видится это происходит вот почему:
1. В классе GraphicsDarkensEffect переопределена виртуальная функция draw, которая вызывается всякий раз, когда источник перерисовывается.
Цитировать
This pure virtual function draws the effect and is called whenever the source needs to be drawn.
2. В Вашем случае источником является объект класса Gf, который меняется по таймеру. Соответственно и функция draw получается что вызывается по таймеру.

P.S. А зачем понадобилось писать класс наследованный от QGraphicsEffect, если как Вы уже сами попробовали, мой способ проще? =)
Записан
Termit
Самовар
**
Offline Offline

Сообщений: 144



Просмотр профиля WWW
« Ответ #9 : Август 04, 2011, 18:33 »

Как мне видится это происходит вот почему:
1. В классе GraphicsDarkensEffect переопределена виртуальная функция draw, которая вызывается всякий раз, когда источник перерисовывается.
Цитировать
This pure virtual function draws the effect and is called whenever the source needs to be drawn.
Все так и есть. Но ожидалось, что перерисовываться будет каждый раз  так сказать "с нуля", а не уже с наложенным эффектом.

2. В Вашем случае источником является объект класса Gf, который меняется по таймеру. Соответственно и функция draw получается что вызывается по таймеру.
P.S. А зачем понадобилось писать класс наследованный от QGraphicsEffect, если как Вы уже сами попробовали, мой способ проще? =)

Этот класс я писал еще до того как Вы выложили свое решение. Ну а по большому счету, лично для меня кажется более правильным подход с созданием эффекта ;-)

PS. В некоторых случаях в Ваше решение тоже затемняется по много раз - если на форме есть QLabel который по таймеру обновляется.
Записан

Человеческая глупость дает представление о бесконечности
(с) Иоанна Хмелевская
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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