2010-01-06 8 views
0

J'essaye d'implémenter une méthode de saisie avec Qt Embedded.Comment faire pour cliquer sur un bouton dans un widget hors-focus sans changer le focus actuel

Il existe une table de correspondance pour choisir les mots candidats à saisir. "zone de saisie de texte" à la "table de recherche" et le mot sélectionné ne peut pas être envoyé à la "zone de saisie de texte".

Dose quelqu'un a une idée pour résoudre ce problème? Merci ~


Ici, je donne un exemple simple:

main.cpp

#include "InputWidget.h" 
#include "ButtonWidget.h" 
#include <QApplication> 

int main(int argc,char *argv[]) 
{ 
    QApplication app(argc,argv); 
    InputWidget *inputWidget=new InputWidget(); 
    ButtonWidget *buttonWidget=new ButtonWidget(); 
    inputWidget->show(); 
    buttonWidget->show(); 
    int ref=app.exec(); 
    inputWidget->deleteLater(); 
    buttonWidget->deleteLater(); 
    return ref; 
} 

InputWidget.h

#include <QWidget> 
#include <QPlainTextEdit> 

#ifndef _InputWidget_H_ 
#define _InputWidget_H_ 

class InputWidget:public QWidget 
{ 
Q_OBJECT 
public: 
    InputWidget(QWidget *parent=0); 
private: 
    QPlainTextEdit *inputArea; 
}; 

#endif 

InputWidget.cpp

#include "InputWidget.h" 
#include <QPushButton> 
#include <QVBoxLayout> 

InputWidget::InputWidget(QWidget *parent):QWidget(parent) 
{ 
    //input area setup 
    inputArea=new QPlainTextEdit(this); 
    //main layout 
    QVBoxLayout *mainLayout=new QVBoxLayout(this); 
    mainLayout->setContentsMargins(1,4,1,1); 
    mainLayout->addWidget(inputArea); 
    setLayout(mainLayout); 
} 

ButtonWidget.h

#include <QWidget> 
#include <QPushButton> 

#ifndef _ButtonWidget_H_ 
#define _ButtonWidget_H_ 

class ButtonWidget:public QWidget 
{ 
Q_OBJECT 
public: 
    ButtonWidget(QWidget *parent=0); 
private: 
    QPushButton *selectedBtn; 
public slots: 
    void changeBtnText(); 
}; 

#endif 

ButtonWidget.cpp

#include "ButtonWidget.h" 
#include <QPushButton> 
#include <QVBoxLayout> 

ButtonWidget::ButtonWidget(QWidget *parent):QWidget(parent) 
{ 
    //selectedBtn setup 
    selectedBtn=new QPushButton(tr("Click Me!!"),this); 
    connect(selectedBtn,SIGNAL(clicked()),this,SLOT(changeBtnText())); 
    //main layout 
    QVBoxLayout *mainLayout=new QVBoxLayout(this); 
    mainLayout->setContentsMargins(1,4,1,1); 
    mainLayout->addWidget(selectedBtn); 
    setLayout(mainLayout); 
} 

void 
ButtonWidget::changeBtnText() 
{ 
    selectedBtn->setText("I am clicked :)"); 
} 

Ces codes généreraient un widget qui a une PlainTextEdit "inputArea" et un widget qui a un bouton "selectedBtn".

D'abord, je saisis quelques mots dans "inputArea". Le foucs actuel est sur "inputArea" dans le InputWidget.

Mais quand je déplace la souris vers ButtonWidget et que je clique sur "selectedBtn", le foucs est changé en "selectedBtn" dans le ButtonWidget. Comment puis-je cliquer sur le "selectedBtn" tout en gardant le foucs sur "inputArea"? Merci ~


Tout comme mon commentaire décrit dans la réponse de laura, InputWidget et ButtonWidget peut avoir aucun parent identique et je ne peux pas utiliser la fente « de setFocus » de QWidget pour changer l'orientation actuelle entre eux.

+0

Vous pourriez vouloir expliquer un peu plus, il est difficile de comprendre ce que vous essayez de faire et ce qui ne va pas. Certains extraits de code peuvent également aider les utilisateurs à vous aider. Cliquez simplement sur "modifier" et mettez à jour votre question. – balpha

Répondre

0

Tout d'abord, vous devrez faire en sorte que les deux widgets se connaissent les uns les autres. Une fois que vous avez fait cela (en plaçant le widget texte dans le widget bouton ou en les ajoutant tous les deux au même widget parent), vous pouvez essayer de voir si le slot setFocus de QWidget peut vous aider utile pour cela).

Peut-être mettre en œuvre quelque chose comme ça, dans le ButtonWidget:

  1. (dans l'en-tête) déclare un signal foo()
  2. (dans le constructeur) connecter le signal de bouton widget foo à fente de setFocusInputWidget
  3. (dans le changeBtnText) une fois que vous avez fait tout ce que vous vouliez, emit foo()

Notez cependant que setFocus fonctionne si la fenêtre est active.

+0

Votre réponse ne convient pas à ma situation car "inputArea" peut se trouver dans n'importe quel autre point d'accès fonctionnant dans l'environnement QT et "selectedBtn" dans le panneau de méthode d'entrée. Ils peuvent être deux programmes indépendants et n'ont pas de parent identique.Mais encore merci pour votre réponse ~~ –

+0

Je vois - ce n'était pas évident à partir de votre exemple, vous pourriez envisager d'ajouter ce commentaire à la question. – laura

0

Vous pourriez obtenir ce que vous voulez en jouant avec le focusPolicy pour votre widget. Faites attention à l'option Qt::NoFocus. Je ne pense pas qu'il empêche les clics de souris sur votre widget, mais vous aurez envie de tester pour être sûr.

+0

J'essaie de définir focusPolicy (Qt :: NoFocus) sur "selectedBtn", mais cela ne fonctionne pas. Après avoir fait quelques tests, je trouve que si je crée un autre "testBtn" PushButton dans ButtonWidget, définissez focusPolicy (Qt :: NoFocus) sur "selectedBtn", et suivez les étapes décrites dans ma question. Le focus continuerait de se transformer en ButtonWidget et le signal clickBtn sélectionné serait toujours déclenché, mais le focus est sur le "testBtn". C'est-à-dire que la politique de concentration ne semble fonctionner qu'avec les widgets qui ont le même parent. Mais toujours merci pour votre réponse ~~ –

0

Merci laura et cjhuitt, vos réponses me donnent un bon indice pour résoudre ma question. Comme InputWidget et ButtonWidget sont deux widgets indépendants, si nous voulons résoudre le problème de mise au point entre eux, nous avons besoin d'un contrôle "global", c'est-à-dire, utilisez QApplication pour effectuer le travail de mise au point.

Le point clé est l'utilisation du slot "focusChanged" de QApplication et de "activateWindow" de QWidget. Ce qui suit est ma modification.

main.cpp

#include "InputWidget.h" 
#include "ButtonWidget.h" 
#include <QApplication> 

int main(int argc,char *argv[]) 
{ 
    QApplication app(argc,argv); 
    InputWidget *inputWidget=new InputWidget(); 
    ButtonWidget *buttonWidget=new ButtonWidget(0,&app); 
    inputWidget->show(); 
    buttonWidget->show(); 
    int ref=app.exec(); 
    inputWidget->deleteLater(); 
    buttonWidget->deleteLater(); 
    return ref; 
} 

ButtonWidget.h

#include <QWidget> 
#include <QPushButton> 
#include <QApplication> 

#ifndef _ButtonWidget_H_ 
#define _ButtonWidget_H_ 

class ButtonWidget:public QWidget 
{ 
Q_OBJECT 
public: 
    ButtonWidget(QWidget *parent=0,QApplication *app=0); 
private: 
    QPushButton *selectedBtn; 
public slots: 
    void changeBtnText(); 
    void changeFocus(QWidget *oldWidget,QWidget *curWidget); 
}; 

#endif 

ButtonWidget.cpp

#include "ButtonWidget.h" 
#include <QPushButton> 
#include <QVBoxLayout> 

ButtonWidget::ButtonWidget(QWidget *parent,QApplication *app):QWidget(parent) 
{ 
    //selectedBtn setup 
    selectedBtn=new QPushButton(tr("Click Me!!"),this); 
    connect(selectedBtn,SIGNAL(clicked()),this,SLOT(changeBtnText())); 
    //main layout 
    QVBoxLayout *mainLayout=new QVBoxLayout(this); 
    mainLayout->setContentsMargins(1,4,1,1); 
    mainLayout->addWidget(selectedBtn); 
    setLayout(mainLayout); 
    //deal with focus 
    connect(app,SIGNAL(focusChanged(QWidget*,QWidget*)),this,SLOT(changeFocus(QWidget*,QWidget*))); 
} 

void 
ButtonWidget::changeBtnText() 
{ 
    selectedBtn->setText("I am clicked :)"); 
} 

void 
ButtonWidget::changeFocus(QWidget *oldWidget,QWidget *curWidget) 
{ 
    if(oldWidget && curWidget==this) 
     oldWidget->activateWindow(); 
} 

InputWidget.cpp et InputWidget ne sont pas modifiés.

Cette solution peut fonctionner dans cet exemple, mais je ne suis pas sûr qu'il puisse fonctionner dans deux programmes Qt indépendants (ils ont leur propre QApplication), en particulier dans l'environnement Qt Embedded. Je continuerais à faire des tests dessus. S'il y a des résultats, je les posterais aussi ici.

Merci pour cette discussion, j'ai beaucoup appris et merci encore !!

+0

Cette solution n'est toujours pas adaptée à la "méthode d'entrée", car le InputWidget enverrait l'événement "focus out" même si je réinitialisais le focus actuel sur InputWidget. L'événement "focus out" permet à la méthode d'entrée de réinitialiser tous les états et les mots sélectionnés sont également annulés. Peut-être que je devrais essayer de trouver d'autres informations sur ce sujet dans QInputContext ou QWSInputMethod. –