Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: DenisG от Июль 14, 2009, 10:22



Название: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 14, 2009, 10:22
Задача: Есть несколько кнопок QPushButton
на всех кнопках есть икноки. Кнопка которая получила фокус должна менять свою икноку.
После потери фокуса она должна востанавливать старую иконку.
Проблема с контролем потери фокуса. смена картинок не проблема.
По форуму поискал - схожые темы есть, но с примерами хуже. 

Если  не сложно, дайте простенький пример для двух кнопок.




Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: spectre71 от Июль 14, 2009, 10:48
virtual void focusInEvent ( QFocusEvent * event )
virtual void focusOutEvent ( QFocusEvent * event )

Переопредели в наследнике QPushButton, либо через eventFilter.


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 14, 2009, 11:19
Cпасибо за ответ. Эти функции видел в документации....
Я специально вопрос задал в разделе для новичков:)
Можно все же полный пример, путаюсь в синтаксисе, так как о сновном пишу на чистом Си и не для PC...
а тут нужда заставила за Qt взяться... 





Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: spectre71 от Июль 14, 2009, 11:36
Поищи по форуму focusInEvent, focusOutEvent.
Найдешь кучу тем и примеров.


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 14, 2009, 13:05
Я  правильно понял, что мне надо создать свой клас на кнопоки и пользоваться уже своим классом?


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: spirit от Июль 14, 2009, 13:08
установи ивент фильтр на кнопари и отлавливай нужные ивенты.
читай про QObject::installEventFilter.


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: spirit от Июль 14, 2009, 13:50
вот пример, файлы с изображениями генерятся на ленту.
h-file
Код
C++ (Qt)
#ifndef TEST_H
#define TEST_H
 
#include <QDialog>
 
class Test: public QDialog
{
Q_OBJECT
 
public:
Test(QWidget *parent = 0);
 
private:
void init();
 
protected:
virtual bool eventFilter(QObject *o, QEvent *e);
 
private:
enum State { FocusIn, FocusOut };
 
int m_rows;
int m_columns;
};
 
#endif//TEST_H
 
cpp-file
Код
C++ (Qt)
#include <QtGui>
#include "test.h"
 
Test::Test(QWidget *parent)
: QDialog(parent), m_rows(5), m_columns(5)
{
init();
}
 
void Test::init()
{
QGridLayout *gl = new QGridLayout(this);
for (int r = 0; r < m_rows; ++r) {
for (int c = 0; c < m_columns; ++c) {
QPushButton *pb = new QPushButton();
pb->setProperty("state", FocusOut);
 
const QString fIn = QString::number(r) + QString::number(c) + "in.png";
const QString fOut = QString::number(r) + QString::number(c) + "out.png";
 
QPixmap fi(100, 100);
fi.fill(QColor(qrand()%255, qrand()%255, qrand()%255));
fi.save(fIn);
 
QPixmap fo(100, 100);
fo.fill(QColor(qrand()%255, qrand()%255, qrand()%255));
fo.save(fOut);
 
pb->setProperty("focusInImageName", fIn);
pb->setProperty("focusOutImageName", fOut);
pb->setText("FocusOut");
pb->setIcon(QIcon(fo));
pb->installEventFilter(this);
gl->addWidget(pb, r, c);
}
}
setFocus();
}
 
bool Test::eventFilter(QObject *o, QEvent *e)
{
QPushButton *pb = qobject_cast<QPushButton *>(o);
if (pb && (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut)) {
const State state = State(pb->property("state").toInt());
pb->setText(state == FocusIn ? "FocusOut" : "FocusIn");
pb->setProperty("state", state == FocusIn ? FocusOut : FocusIn);
const QString fileName = (state == FocusIn ? pb->property("focusOutImageName").toString() : pb->property("focusInImageName").toString());
pb->setIcon(QIcon(fileName));
}
return QDialog::eventFilter(o, e);
}
 
main.cpp
Код
C++ (Qt)
#include <QApplication>
#include "test.h"
 
int main(int argc, char **argv)
{
QApplication app(argc, argv);
 
Test test;
test.show();
 
return app.exec();
}
 


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 14, 2009, 14:19
Спасиб! буду изучать!


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: spectre71 от Июль 14, 2009, 14:33
Я  правильно понял, что мне надо создать свой клас на кнопоки и пользоваться уже своим классом?

Да, Сначала сделай так.
 
Код
C++ (Qt)
class MyPushButton : public QPushButton {
 Q_OBJECT
 
 public:
   MyPushButton ( QWidget * parent = 0) : QPushButton(parent) {}
   ~MyPushButton () {}
...
...
 protected:
   virtual void focusInEvent ( QFocusEvent * event );
   virtual void focusOutEvent ( QFocusEvent * event );
};
 

eventFilter - попробуешь когда получше разберешся.


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: BRE от Июль 14, 2009, 14:43
Думаю, можно попробовать добиться такого поведения используя StyleSheet.


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 14, 2009, 17:06
Спасибо за примеры.
Все  поковыряю в порядке поступления.
Снала eventFilter - потом через клас.

to BRE - на StyleSheet у меня и работает так две кнопки.
Одну нажал  - сменил ее картинку - надругой востановил старую.
Кнопок будет с десяток. Это будет печально.

Для меня  очень важно быстродействие этого приложения.
Поэтому перепробую все - где быстрее будет фурыкать то и оставлю.
Платформа 200МГц всего;)   На такой скорости сразу заметно торможения во время конекта сигнала и слотоа. буквально больше 3 конектов и тормоза полные;)


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: BRE от Июль 14, 2009, 17:20
Платформа 200МГц всего;)   На такой скорости сразу заметно торможения во время конекта сигнала и слотоа. буквально больше 3 конектов и тормоза полные;)
Неужели всего три коннекта успевает....  ;)
Даааа, ослабли двести мегагерцовые машины, совсем плохие стали.  ;)

Вроде, такое поведение можно сделать установив один раз стиль для виджета на котором находятся эти кнопки....


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 14, 2009, 17:38
ща посчитал реально я тестил 8 конектов слайдеры друг за друга цеплял - тормоза заметные
за удобство всегда приходиться расплачиваться ресурсами....

На тему StyleSheet - пример в студию!

собрал на таргет пример spirit-а - шустро все работает;) 25 кнопарей


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: BRE от Июль 14, 2009, 18:20
ща посчитал реально я тестил 8 конектов слайдеры друг за друга цеплял - тормоза заметные
за удобство всегда приходиться расплачиваться ресурсами....
А можно подробней, что за коннекты. Желательно с куском кода. А то мне не совсем понятно.

На тему StyleSheet - пример в студию!
Все правила описывается в одном файле и устанавливаются для родительского виджета.
Кнопкам назначаются имена. Далее примерно так:
Код:
QPushButton#button1 {
    image: url( image1.png );
}

QPushButton#button1:focus {
    image: url( image1_focused.png );
}

QPushButton#button2 {
    image: url( image2.png );
}

QPushButton#button2:focus {
    image: url( image2_focused.png );
}

...


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 14, 2009, 18:35
Код:
   QObject::connect(ui->dial, SIGNAL(valueChanged(int)), ui->verticalSlider, SLOT(setValue(int)));
    QObject::connect(ui->dial, SIGNAL(valueChanged(int)), ui->horizontalSlider, SLOT(setValue(int)));

    QObject::connect(ui->verticalSlider, SIGNAL(valueChanged(int)), ui->horizontalSlider, SLOT(setValue(int)));
    QObject::connect(ui->verticalSlider, SIGNAL(valueChanged(int)), ui->dial, SLOT(setValue(int)));

    QObject::connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->verticalSlider, SLOT(setValue(int)));
    QObject::connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->dial, SLOT(setValue(int)));

    QObject::connect(ui->dial, SIGNAL(valueChanged(int)), ui->lcdNumber, SLOT(display(int)));
    QObject::connect(ui->dial, SIGNAL(valueChanged(int)), ui->progressBar, SLOT(setValue(int)));


BRE а можно примерчик как сделал spirit - для чайников)



Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: BRE от Июль 14, 2009, 19:31
BRE а можно примерчик как сделал spirit - для чайников)


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 15, 2009, 11:15
Супер! Попробывал на таргете - все пучком!
thx!


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: BRE от Июль 15, 2009, 11:16
Супер! Попробывал на таргете - все пучком!
thx!
+ сколько всего красивого можно там навертеть....


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 15, 2009, 14:36
навернуть можно;)

с юзанием фокуса особенность забавная выяснилась.
Мне вообще фокусить кнопки не требовалось и чтобы небыло рамки я ставил свойства nofocus.
А тут надо разрешать фокусить кнопки и задавать border 0й толщины.
На PC рамки нет - а на таргете зараза появляется...
пытаюсь разобраться.....


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: BRE от Июль 15, 2009, 14:58
с юзанием фокуса особенность забавная выяснилась.
Мне вообще фокусить кнопки не требовалось и чтобы небыло рамки я ставил свойства nofocus.
А тут надо разрешать фокусить кнопки и задавать border 0й толщины.
На PC рамки нет - а на таргете зараза появляется...
пытаюсь разобраться.....
Попробуй:
{ border-style: none; }


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 15, 2009, 15:18
;) пробoвал
там какой то замут со стилем запуска приложение на таргете
если я стартую ./qtdemo -qws     
когда топчу пальцем по тачскрину -кнопки с икнами красиво нажимаются - как бы продавливаются и когда отпускаешь тачскрин кнопка возращается на место
 (на pc продавливается только кнопка а икна на месте)
Но БОРДЕР есть, не смотря на border-style: none;
а если запускаться
./qtdemo -qws -style cleanlooks
бордера нету. Но кнопари при нажатии на тачсрин остаются на месте. А икноки меняются так как в твоем примере нормально.

В конечном итоге надо, что бы нажатая один раз кнопка продавливалась(эфект физического нажимания) и после отпускания на ней было изображение (аля она в фокусе)
Есть подозрение, что придется вернуться к eventFilter







Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: BRE от Июль 15, 2009, 15:31
Есть подозрение, что придется вернуться к eventFilter
Смотри сам, но почитать assistent по CSS я тебе рекомендую, там все это флагами настраивается и сдвиги картинки/текста при нажатии и куча всего еще.  ;)
Зато внешний вид интерфейса можно будет менять редактированием одного файла.


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 15, 2009, 15:43
вот как раз сейчас почитываю%)


Название: Re: Потеря фокуса QPushButton (примерчик)
Отправлено: DenisG от Июль 15, 2009, 16:13
Все разрулил..
не { border-style: none; }
а { border: none; }

а для эфекта нажатия мне понравился
{padding: -6px;}