2016-07-19 2 views
0

Предпосылки:Сбой при вызове GetOpenFileName из QItemDelegate в собственном редакторе

У меня есть обычай QItemDelegate, который создает пользовательский редактор для элементов TreeView. Редактор состоит из 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); 
} 

ответ

0

Я сделал некоторые раскопки и выяснил, что вызов WinAPI результатов функции GetOpenFileName в том же образом: мой редактор будет удален (хотя авария не бывает). Кажется, что Qt называет это также внутренне.

Я отследил причину того, почему мой редактор удаляется и выясняется, что при вызове getOpenFileName с ним меняются активные изменения окна и фокус. В первом случае фокус перемещается из элемента TreeView, но во втором случае он перемещается из самого редактора! Это приводит к удалению редактора из-за события «focus out».

Важно сказать, что эта ситуация не возникает, если флаг «DontUseNativeDialog» задается при создании диалогового окна файла. Поэтому это должно быть ошибкой в ​​управлении окнами Qt между родными окнами и виджетами Qt.

Как обход этой ошибки я предлагаю следующее решение: перед вызовом getOpenFileName установить фокус на кнопку непосредственно.

m_pUI->RunSetupBtn->setFocus(); 

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

Другой обходной путь заключается в использовании флага «DontUseNativeDialog», но диалог полученный файл не выглядит родной, на самом деле это довольно некрасиво. Если у кого-то есть лучшее решение, не стесняйтесь делиться ими.

0

У меня есть аналогичная проблема с getOpenFileName и getSaveFileName. Мое решение - после getOpenFileName, getSaveFileName или в конце функции установить окна как активные с помощью activateWindow().

Смежные вопросы