如果所有儿童小部件都失去焦点,则发出信号

时间:2011-09-11 04:24:16

标签: qt

我有一个QStackedWidget,其中包含多个页面,其中包含各种QLineEditQComboBox个孩子。我想在QStackedWidget不再具有任何具有焦点的孩子时发出信号(假设孩子有焦点开始)。因此,从孩子到孩子的移动不会发出信号,但是一旦在QStackedWidget之外选择了一个小部件,就会发出信号。关于如何实现这一点的任何建议?我查看了InstallEventFilterQSignalMapper,但这些都不符合我的需求。任何建议将不胜感激。

2 个答案:

答案 0 :(得分:4)

您可以连接到QApplication :: focusChanged信号,以评估相应插槽中的焦点小部件。干净的方法是从QStackedWidget派生:

class StackedFocusWidget : public QStackedWidget {

    Q_OBJECT

public:

    StackedFocusWidget(QWidget *parent = 0) : QStackedWidget(parent) {
        connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)), this, SLOT(onFocusChanged(QWidget *, QWidget *)));
    }

private slots:

    void onFocusChanged(QWidget *old, QWidget *now) {
        bool focusOld = old != 0 && isAncestorOf(old);
        bool focusNow = now != 0 && isAncestorOf(now);
        if (!focusOld && focusNow) {
            emit gotFocus();
        } else if (focusOld && !focusNow) {
            emit lostFocus();
        }
    }

signals:

    void gotFocus();
    void lostFocus();
};

StackfulFocusWidget :: gotFocus和StackedFocusWidget :: lostFocus信号将在堆叠小部件或其任何子节点接收或失去焦点时发出。

答案 1 :(得分:2)

这有点棘手。即使从孩子到孩子骑车,在孩子失去焦点之后的短暂时期内,在另一个孩子获得焦点之前,堆叠的小部件的孩子没有焦点。虽然这种状态非常短暂,但这是事实。

我能看到的唯一选择是确定一个子窗口小部件失去焦点和没有子窗口小部件获得焦点之间的时间长度,你会认为它足够长,足以声明确实没有子窗口小部件具有焦点。这将是一种类似于用于区分两次单击鼠标和双击的机制。

这可以通过在每个孩子注册的父母中使用计时器和事件过滤器来实现,该过滤器查找焦点进出事件。将定时器设置为某个间隔(100 ms?)并在收到焦点输出事件时启动它。如果在计时器仍在运行时收到焦点,请停止计时器。如果计时器完成,您可以发出自己的信号,以指示没有子窗口小部件具有焦点。