Название: Перехват фокуса в дочерних виджетах
Отправлено: Fregloin от Июнь 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()); }
Проблема, как сделать так, что бы отловить событие получение фокуса моим виджетом, затем отобразить кнопку, а потом установить фокус ввода на дочерний виджет, при этом отловить потерю фокуса уже в дочернем виджете что бы кнопка исчезла.
Название: Re: Перехват фокуса в дочерних виджетах
Отправлено: GreatSnake от Июнь 07, 2011, 13:22
Про делегаты я слышал но пока не вникал. А зря, т.к. не мешало бы вникнуть, чтобы не городить такой огород.
Название: Re: Перехват фокуса в дочерних виджетах
Отправлено: Fregloin от Июнь 07, 2011, 13:59
я и вникну, но позже, так как надо сделать готовую прогу чем быстрее тем лучше, минимально работающий вариант.
Название: Re: Перехват фокуса в дочерних виджетах
Отправлено: GreatSnake от Июнь 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() для этого не рассчитан.
Название: Re: Перехват фокуса в дочерних виджетах
Отправлено: Fregloin от Июнь 09, 2011, 12:18
а где можно почитать про делегаты, в моем случае что бы реализовать подобный инспектор объектов, как в самом креаторе или наподобие делфи? свойств отображаться будет не много, порядка 4-10, максимум 15.
Название: Re: Перехват фокуса в дочерних виджетах
Отправлено: GreatSnake от Июнь 09, 2011, 12:45
а где можно почитать про делегаты, в моем случае что бы реализовать подобный инспектор объектов, как в самом креаторе или наподобие делфи? свойств отображаться будет не много, порядка 4-10, максимум 15.
Программирование модель/представление (http://doc.crossplatform.ru/qt/4.6.x/model-view-programming.html). Готовый QPropertyEditor (http://qt-apps.org/content/show.php/QPropertyEditor?content=68684) виджет. Там же много чего ещё найдёшь)
|