如果所有子窗口小部件失去焦点,请发出信号

5
我有一个包含多个QLineEdit和QComboBox的页面的QStackedWidget。当QStackedWidget不再拥有任何子元素获得焦点时(假设初始情况下至少有一个子元素获得了焦点),我想要发射一个信号。因此从一个子部件移动到另一个子部件不会发射信号,但一旦选择了QStackedWidget之外的部件,就会发出信号。请问如何实现这个功能?我已经查看了InstallEventFilter和QSignalMapper,但它们似乎都不符合我的需求。希望能得到任何建议。
2个回答

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();
};

每当堆叠窗口控件或其任何子窗口接收或失去焦点时,都会发出信号StackedFocusWidget::gotFocus和StackedFocusWidget::lostFocus。

1

这有点棘手。即使从子部件到子部件循环,也会在一个子部件失去焦点并且另一个子部件获得焦点之前有一个短暂的时期,在这个时间段内,堆叠窗口小部件中没有任何子窗口小部件具有焦点。虽然这种状态非常短暂,但这是事实。

我唯一能看到的选择是决定在一个子窗口小部件失去焦点并且没有其他子窗口小部件获得焦点的时间间隔有多长,您认为足以宣布确实没有任何子窗口小部件拥有焦点。这将是一种类似于用于区分两个单击鼠标与双击鼠标的机制。

这可以通过在父级上注册每个子级别的计时器和事件过滤器来实现,该计时器和事件过滤器寻找焦点进出事件。将计时器设置为一些间隔(100毫秒?),并在接收到焦点离开事件时启动它。如果在计时器仍在运行时接收到焦点进入事件,则停止计时器。如果计时器完成,则可以触发自己的信号以指示没有任何子窗口小部件具有焦点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接