0

前提条件:

ツリービュー項目のカスタム エディターを作成するカスタム QItemDelegate があります。エディターは、QLineEdit と QToolButton で構成されます。このボタンを使用して、ファイルを選択し、そのパスを行編集に配置するためのファイル ダイアログを開きます。QFileDialog::getOpenFileName への呼び出しを使用して、ファイル ダイアログを開きます。ダイアログはネイティブの Windows ファイル ダイアログです (これは重要です)。

エディターが初めて作成されたときは、そのボタンを何度押してもすべて正常に機能します。しかし、エディターを閉じて再度開いた後、ボタンを最初に押すとクラッシュします。クラッシュの理由は、私のカスタム エディターが最終的に削除されることです。

ここにいくつかのコードがあります:

void CCustomEditor::on_RunSetupBtn_clicked()
{
    auto qFilename = QFileDialog::getOpenFileName(this,
        "Select application to run",
        QString(),
        "Executable files (*.exe)");

    if (qFilename.isEmpty())
        return;

    SetCommandLine(QDir::toNativeSeparators(qFilename), m_qParameters);
}
4

2 に答える 2

0

掘り下げてみたところ、WinAPI 関数 GetOpenFileName を呼び出すと、まったく同じ結果になることがわかりました。エディターが削除されます (ただし、クラッシュは発生しません)。Qtも内部で呼び出しているようです。

エディターが削除される理由を突き止めたところ、getOpenFileName が呼び出されると、アクティブなウィンドウが変更され、フォーカスが変更されることがわかりました。最初のケースでは、フォーカスは TreeView アイテムから移動されますが、2 番目のケースでは、エディター自体から移動されます! これにより、「フォーカス アウト」イベントのためにエディターが削除されます。

ファイルダイアログの作成時に「DontUseNativeDialog」フラグが設定されている場合、この状況は発生しないことに注意してください。したがって、これはネイティブ ウィンドウと Qt ウィジェット間の Qt のウィンドウ管理のバグであるはずです。

このバグの回避策として、次の解決策をお勧めします: getOpenFileName を呼び出す前に、フォーカスをボタン自体に設定します。

    m_pUI->RunSetupBtn->setFocus();

    auto qFilename = QFileDialog::getOpenFileName(this,
            "Select application to run",
            QString(),
            "Executable files (*.exe)");

もう 1 つの回避策は、'DontUseNativeDialog' フラグを使用することですが、結果として得られるファイル ダイアログはネイティブに見えず、実際には非常に醜いものです。誰かがより良い解決策を持っている場合は、自由に共有してください。

于 2016-07-19T10:48:32.647 に答える
0

getOpenFileName と getSaveFileName にも同様の問題があります。私の解決策は、getOpenFileName、getSaveFileName の後、または関数の最後に activateWindow() でウィンドウをアクティブに設定することです。

于 2017-12-01T15:55:04.260 に答える