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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Перехват фокуса в дочерних виджетах  (Прочитано 7462 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Июнь 07, 2011, 13:05 »

Пишу свой инспектор объектов для миниSCADA.
Создал наследника от QWidget EditableWidget, задача которого разместить в себе дочерний виджет (обычно это будет либо lineEdit либо textEdit).
При получении фокуса, будет рядом отображаться кнопка с текстом "...", при нажатии на которую нужно послать сигнал.
При потере фокуса кнопка исчезает. Суть понятна, это стандартная фишка всех инспекторов объектов.
Сами эти виджеты я распологаю в таблице методом setCellWidget. Про делегаты я слышал но пока не вникал. при чем, виджеты будут встраиваться разные.
Код:
QEditableWidget::QEditableWidget(QWidget *parent) :
    QWidget(parent)
{
    ftoolButton = NULL;
    feditableWidget = NULL;
    setFocusPolicy(Qt::ClickFocus);
}

void        QEditableWidget::setEditableWidget(QWidget  * EditableWidget)
{
    if(feditableWidget!=EditableWidget)
    {
        setUpdatesEnabled(false);
        if(feditableWidget)
        {
            setFocusProxy(NULL);
            delete feditableWidget;
            delete ftoolButton;
        }
        feditableWidget = EditableWidget;
        if(feditableWidget)
        {
            feditableWidget->setParent(this);
            feditableWidget->setFocusPolicy(Qt::NoFocus);
            feditableWidget->setGeometry(rect());
        }
        setUpdatesEnabled(true);
    }
}

void    QEditableWidget::focusInEvent(QFocusEvent * event)
{
    if(feditableWidget)
    {
        feditableWidget->setGeometry(rect().adjusted(-1,-1,geometry().width()-geometry().height(),0));
    }
    ftoolButton = new QToolButton;
    ftoolButton->setText("...");
    ftoolButton->setParent(this);
    ftoolButton->setGeometry(rect().adjusted(geometry().width()-geometry().height(),-1,-1,0));
    ftoolButton->show();
    connect(ftoolButton,SIGNAL(clicked()),this,SIGNAL(editButtonClicked()));
    QWidget::focusInEvent(event);
}

void    QEditableWidget::focusOutEvent(QFocusEvent * event)
{
    QWidget::focusOutEvent(event);
    delete ftoolButton;
    if(feditableWidget) feditableWidget->setGeometry(rect());
}
Проблема, как сделать так, что бы отловить событие получение фокуса моим виджетом, затем отобразить кнопку, а потом установить фокус ввода на дочерний виджет, при этом отловить потерю фокуса уже в дочернем виджете что бы кнопка исчезла.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Июнь 07, 2011, 13:22 »

Цитировать
Про делегаты я слышал но пока не вникал.
А зря, т.к. не мешало бы вникнуть, чтобы не городить такой огород.
Записан

Qt 5.11/4.8.7 (X11/Win)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #2 : Июнь 07, 2011, 13:59 »

я и вникну, но позже, так как надо сделать готовую прогу чем быстрее тем лучше, минимально работающий вариант.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Июнь 08, 2011, 12:40 »

я и вникну, но позже, так как надо сделать готовую прогу чем быстрее тем лучше, минимально работающий вариант.
Вот тебе более-менее работающий пример:
Код
C++ (Qt)
#include <QApplication>
#include <QTableWidget>
#include <QLineEdit>
#include <QToolButton>
#include <QHBoxLayout>
 
class CellLineEdit : public QWidget
{
public:
CellLineEdit( QWidget* p = 0 )
: QWidget( p )
{
QHBoxLayout* l = new QHBoxLayout( this );
l->setContentsMargins( 0, 0, 0, 0 );
l->setSpacing( 0 );
 
le_ = new QLineEdit;
le_->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
l->addWidget( le_ );
 
btn_ = new QToolButton;
btn_->setText( "..." );
btn_->setFocusPolicy( Qt::NoFocus );
btn_->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
btn_->hide();
l->addWidget( btn_ );
 
setFocusPolicy( Qt::StrongFocus );
 
le_->installEventFilter( this );
}
bool eventFilter( QObject* o, QEvent* e )
{
if( o == le_ )
{
if( e->type() == QEvent::FocusIn )
btn_->show();
else if( e->type() == QEvent::FocusOut )
btn_->hide();
}
return false;
}
void focusInEvent( QFocusEvent* e )
{
QWidget::focusInEvent( e );
le_->setFocus();
}
 
QLineEdit* le_;
QToolButton* btn_;
};
 
int main( int argc, char** argv )
{
QApplication app( argc, argv );
QTableWidget tw;
 
tw.setRowCount( 5 );
tw.setColumnCount( 5 );
 
for( int i = 0; i < tw.rowCount(); i++ )
for( int j = 0; j < tw.columnCount(); j++ )
tw.setCellWidget( i, j, new CellLineEdit );
 
tw.show();
return app.exec();
}
 
Сигналы на кнопку повесишь сам)
Только я никак не могу понять почему-то при нажатии на кнопку она не отжимается Грустный
Имхо, вся бодяга с фокусом должна решаться через делегаты и cellWidget() для этого не рассчитан.
Записан

Qt 5.11/4.8.7 (X11/Win)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #4 : Июнь 09, 2011, 12:18 »

а где можно почитать про делегаты, в моем случае что бы реализовать подобный инспектор объектов, как в самом креаторе или наподобие делфи?
свойств отображаться будет не много, порядка 4-10, максимум 15.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Июнь 09, 2011, 12:45 »

а где можно почитать про делегаты, в моем случае что бы реализовать подобный инспектор объектов, как в самом креаторе или наподобие делфи?
свойств отображаться будет не много, порядка 4-10, максимум 15.
Программирование модель/представление.
Готовый QPropertyEditor виджет. Там же много чего ещё найдёшь)
Записан

Qt 5.11/4.8.7 (X11/Win)
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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