PDA

View Full Version : Changing active window in my SDI application doesn't always work.



portilhe
4th March 2011, 20:18
Howdy,

In this exciting process of learning Qt, I am trying to change the "basic"-part example from the "C++ GUI Programming with Qt 4" book (chapters 1--4) from a one window app to a multiple window one. The application is a (very basic) spreadsheet.

The class MainWindow inherits from QMainWindow; each instance is a single document window. The class Spreadsheet inherits from QTableWidget and each MainWindow has a Spreadsheet as a Central Widget. I have this working pretty well, except when I want to activate a window (one which is not currently active) in the following situation: when the user, from the currently active window, chooses to open a document which is open in a different window. The code I wrote to achive this is:


bool MainWindow::loadFile(const QString &fileName)
{
if (!raiseWhenOpened(fileName)) {
if (!spreadsheet->readFile(fileName)) {
statusBar()->showMessage(tr("Loading canceled"), 2000);
return false;
}

setCurrentFile(fileName);
statusBar()->showMessage(tr("File loaded"), 2000);
return true;
}
return false;
}

bool MainWindow::raiseWhenOpened(const QString &fileName)
{
foreach (QWidget *wid, QApplication::topLevelWidgets()) {
if (MainWindow *mainWin = qobject_cast<MainWindow *>(wid)) {
if (mainWin->curFile == fileName) {
QMessageBox::information(this, tr("Spreadsheet"),
"The file \""+ strippedName(fileName) +
"\" is already open in another window.");
mainWin->raise();
mainWin->show();
mainWin->activateWindow();
mainWin->setFocus();
return true;
}
}
}
return false;
}

curFile is a QString type member of MainWindow holding the name of the file opened in that window. I put the QMessageBox there mainly as a breakpoint and to check that mainWin is pointing to the right thing (which it is). I've tried several combinations of the mainWin function calls raise(), show(), activateWindow() and setFocus(). The current behavior is that it makes mainWin be on top of the currently active window (this), but it does not make mainWin active (it doesn't have the focus).

The odd thing is that when I create a new window (from the file->new menu or Ctrl+N) this code

void MainWindow::newFile()
{
if (okToContinue()) {
MainWindow *mainWin = new MainWindow;
mainWin->show();
}
does work and the new window has the focus (okToContinue checks whether the user wants to save changed documents, etc.).

I've searched for problems using activateWindow() and I found several issues, but I believe none of them in this situation. Since I am new to Qt, there's a high probability that I am doing something silly, and I'd be much obliged for any help.

I am runnig Qt 4.6.2 on Ubuntu 10.04 under Gnome.

Cheers, Manu