0

Qt4 を使用してプロジェクトを開発していますが、わずかな問題が発生しました。メインウィンドウからモーダルウィンドウを作成しています。上部のツールバーを無効にしたい。メニューからモーダルを生成するメニュー項目があります。私が欲しいのは、モーダルが生成されたときにメニューが無効になることです。setEnabled(false) 関数を使用してみましたが、リセットされません。

コードは次のとおりです。

void Main_Screen::Create_ViPro()
{
   std::auto_ptr<ViPro_Dialog> modal(new ViPro_Dialog(this));
   modal->show();
   modal->exec();
}

したがって、メニュー項目が選択されたときにトリガーされる単純なクラスです。親をメイン画面に設定していることが問題の原因だと思いますが、親なしでモーダルを作成する方法がわかりません(それを行う意味がありません)。子から親のツールバーを無効にする方法はありますか? これまでに見た唯一のものは _fileMenu->setEnabled(false); です。モーダルを作成しない限り機能しますが、モーダルが生成されるとすぐに、メニューが再び機能します。私は完全に迷っています。前もって感謝します

パトリスとして編集

ここにコンストラクタがあります

    Main_Screen::Main_Screen(QWidget* parent /*= NULL*/) 
                        : QMainWindow(parent),
                          _newProj(new QAction(tr("New &ViPro"), this)),
                          _fileMenu(menuBar()->addMenu(tr("&File")))
{    
  //create slot for creating a new project
  connect(_newProj.get(), SIGNAL(triggered()), this, SLOT(Create_ViPro()));
  _fileMenu->addAction(_newProj.get());
  //if i do this then setEnabled(false) works perfectly and i can't access the menu
  Create_ViPro()
}

そのため、関数は newproject アクションをトリガーすることによって通知されます。コンストラクター内から関数を直接呼び出すと、パトリスが述べたように無効になりますが、トリガーを介して関数を呼び出すと、無効になりません。シグナル/スロットメカニズムの処理が間違っていますか? 再度、感謝します。

別の例として、以下のように関数 create_vipro() を作成した場合

void Main_Screen::Create_ViPro()
{
     _fileMenu->setEnabled(false);
}

イベントをトリガーしてもファイル メニューは無効になっていないため、モーダル自体とは関係なく、シグナルの処理方法に関係している必要があります。

4

2 に答える 2

0

を使用exec()すると、モーダル ダイアログが作成されるだけでなく、通常のイベント処理のほとんどが中断され、 にあるダイアログのイベントのみが処理されexec()ます。これにはいくつかの UI の更新 (有効から無効への移行など) が含まれる可能性がありますが、私は肯定的ではありません。これを処理するより良い方法は、ダイアログのモーダルを明示的に設定することですが、次のように通常のイベント ループを続行できるようにすることです。

void Main_Screen::Create_ViPro()
{
   ViPro_Dialog* modal = new ViPro_Dialog(this);
   modal->setModal(true);
   modal->show();
}

そのコードは、ツールバーまたはメニューバーを視覚的に無効にすることはありませんが、応答しないはずです。それらを無効にするには、これをPatrice Bernassola's answerと組み合わせてみてください。

于 2012-04-17T18:14:49.547 に答える
0

child はモーダル ダイアログのメイン画面であるため、イベントに反応できません。ただし、モーダル ダイアログを作成する前にツールバー (またはメニューバー) を無効にし、exec 関数を離れるとすぐに有効にすることができます。

void Main_Screen::Create_ViPro()
{
   _fileMenu->setEnabled(false);

   std::auto_ptr<ViPro_Dialog> modal(new ViPro_Dialog(this));
   modal->show();
   modal->exec(); // Will stay here until you close the modal dialog

   _fileMenu->setEnabled(true);
}

ViPro_Dialog が実際にモーダル ダイアログである場合、動作します。

もう 1 つ、ViPro_Dialog はモーダルであるため、auto_ptr を使用せずにローカルで宣言できます。

void Main_Screen::Create_ViPro()
{
   _fileMenu->setEnabled(false);

   ViPro_Dialog modal(this);
   modal.show();
   modal.exec(); // Will stay here until you close the modal dialog

   _fileMenu->setEnabled(true);
}

編集:

QActionを実行しているときにメニューを有効/無効にできないと思います(仕事でテストできません)。Signal はスロットを順番に呼び出しているため、メニューを無効にしようとすると QAction がビジーになります。これを試して:

  1. メイン画面で、メニューバーを有効/無効にする 1 つのブール値パラメーターを持つスロットを作成します。setEnabled 関数を呼び出すだけです
  2. ViPro_Dialog で、ブール値パラメーター (起動時に false、検証時に true) を使用して信号を送信します。
  3. Create_ViPro で、ダイアログが作成されたら、新しい信号をスロットに接続し、ダイアログを実行し、信号からスロットを切断することを忘れないでください。

void Main_Screen::Create_ViPro() { ViPro_Dialog modal(this);

// シグナル/スロットを接続

modal.show(); modal.exec(); // モーダル ダイアログを閉じるまでここにとどまります

// シグナル/スロットを切断 }

これはあなたが望むものを達成することができます

EDIT2

モーダル ダイアログを使用するときに間違いを犯しています。と の間に競合がshow()ありexec()ます。モーダル ダイアログを表示している場合、他のウィンドウを無効にする必要はありません。これは、ダイアログのモーダル ステータスによって自動的に行われます。多くのモーダル深度があります: http://qt-project.org/doc/qt-4.8/qt.html#WindowModality-enum。したがって、コードは次のようになります。

void Main_Screen::Create_ViPro()
{
   ViPro_Dialog modal(this);

   // modal.setWindowModality(Qt::WindowModal); // Uncomment this line if you want to only disable parent

   modal.exec();
}

詳細については、http: //qt-project.org/doc/qt-4.8/QDialog.html#detailsを参照してください。

于 2012-04-17T10:52:00.510 に答える