Monday, April 25, 2011

simple qt: detect when the current window becomes active

for my simple xbmc remote, i wanted to be notified somehow when the main window loses or gains the focus and the custom screen saver is active, so that i can deactivate it while the app is not in focus.

without this, you could get your screen dimmed or locked by the simple xbmc remote, even though you were actually doing something completely different and the app was somewhere in the background.

my first approach was to create a timer and interrogate periodically the main window if it is still the active one (via QWidget::isActiveWindow). not very elegant.

a nicer approach is to connect to the QApplication::focusChanged signal.

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();

private slots:
  void onApplicationFocusChanged(QWidget* old, QWidget* now);

private:
  Ui::MainWindow *m_ui;
};

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  m_ui(new Ui::MainWindow)
{
  m_ui->setupUi(this);

  connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)),
    this, SLOT(onApplicationFocusChanged(QWidget*,QWidget*)));
}

MainWindow::~MainWindow()
{
  delete m_ui;
}

void MainWindow::onApplicationFocusChanged(QWidget *old, QWidget *now)
{
  if (old == 0 && isAncestorOf(now) == true)
    qDebug("focus IN");
  else if (isAncestorOf(old) == true && now == 0)
    qDebug("focus OUT");
}


for the simple xbmc remote, i also wanted to detect focus changes due to menu activations, so the final code looks more like this:

void MainWindow::onApplicationFocusChanged(QWidget */*old*/, QWidget */*now*/)
{
  bool current_state = isActiveWindow();
  if (current_state != m_prevActivatedState) {
    m_prevActivatedState = current_state;
    if (current_state) {
      qDebug("focus IN");
    } else {
      qDebug("focus OUT");
    }
  }
}

1 comment:

  1. Thanks a lot. This was a big help.

    ReplyDelete