开发者

How to click a button in a out-of-focus widget without changing the current focus to it

I am trying to implement a input method with Qt Embedded.

There is a lookup table for choosing the candidate words for typing. "text input area" to the "lookup table" and the selected word cannot be sent to the "text input area".

Dose anyone have any idea to solve this problem? Thanks~


Here I give a simple example:

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);
  开发者_JAVA技巧  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 :)");
}

Those codes would generate a widget which has a PlainTextEdit "inputArea" and a widget which has a PushButton "selectedBtn".

First, I input some words in the "inputArea". The current foucs is on "inputArea" in the InputWidget.

But when I move mouse to ButtonWidget and click the "selectedBtn", the foucs is changed to "selectedBtn" in the ButtonWidget.

How do I click the "selectedBtn" but still keep the foucs on "inputArea"? Thanks~


Just like my comment described in laura's answer, InputWidget and ButtonWidget may have no identical parent and I cannot use QWidget's "setFocus" slot to change the current focus between them.


First of all, you will need to make the two widgets know about each other. Once you have done that (by setting the text widget into the button widget or by adding them both to the same parent widget), you can try to see if QWidget's setFocus slot can help you (look at the other slots too, some might be useful for this).

Perhaps implement something like this, in the ButtonWidget:

  1. (in the header) declare a signal foo()
  2. (in the constructor) connect button widget's foo signal to InputWidget's setFocus slot
  3. (in the changeBtnText) after you've done everything you wanted, emit foo()

Note though that setFocus works if the window is active.


You might be able to get what you want by playing with the focusPolicy for your widget. Pay attention to the Qt::NoFocus option. I don't think it prevents mouse clicks on your widget, but you'll want to test to be sure.


Thank laura and cjhuitt, your responses give me a big hint to solve my question.

Because InputWidget and ButtonWidget are two independent widgets, if we want to deal with the focus issue between them, we need a "global" control, i.e., use QApplication to do the focus job.

The key point is using QApplication's "focusChanged" slot and QWidget's "activateWindow". The following is my 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 and InputWidget are not modified.

This solution can work in this example, but I am not sure that it can work in two independent Qt programs(they have their own QApplication), especially in Qt Embedded environment. I would continue doing some tests on it. If there are any results, I would also post them here.

Thank for this discussion, I have learned a lot and thank you all again!!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜