QT模态窗口和禁用父项工具栏

时间:2012-04-17 00:19:23

标签: c++ qt user-interface qt4 toolbar

我正在使用Qt4开发一个项目,我遇到了一个小问题。 我正在从主窗口创建一个模态窗口。我希望这能禁用顶部的工具栏。 我有一个菜单项,从菜单中生成模态。我想要的是,当产生模式时,菜单被禁用。我尝试过使用setEnabled(false)函数,但是没有重置它。

以下是代码:

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

所以这只是一个选择菜单项时触发的简单类。我觉得这个问题源于我将父级设置为主屏幕的事实,但是我不知道如何在没有父级的情况下创建模式(这样做没有意义)。有没有办法禁用孩子的父母工具栏?到目前为止我唯一看到的是_fileMenu-&gt; setEnabled(false); 只要我不创建模态,这就有效,但只要产生模态,菜单就会再次运行。我完全迷失了。 提前致谢

编辑为Patrice

这是构造函数

    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动作来发出信号。如果我直接从构造函数中调用该函数,它会像你所说的patrice一样禁用它,但是,如果我通过触发器调用了函数,它就不会禁用它。我处理信号/插槽机制错了吗?再次感谢。

另一个例子,如果我将函数create_vipro()创建如下

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

当我触发事件时,文件菜单没有被禁用,因此它必须与模态本身无关,而是与信号的处理方式无关。

2 个答案:

答案 0 :(得分: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确实是一个模态对话框,它将起作用。

另一件事,因为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时无法启用/禁用菜单。信号正在顺序调用插槽,因此当您尝试禁用菜单时QAction正忙。 试试这个:

  1. 在主屏幕中,创建一个带有一个布尔参数的插槽,用于启用/禁用菜单栏。只需调用setEnabled函数
  2. 即可
  3. 在ViPro_Dialog中,使用布尔参数发出信号(启动时为false,验证时为true)
  4. 在Create_ViPro中,创建对话框后,将新信号与插槽,exec对话框连接,不要忘记将插槽与信号断开连接:
  5. 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

答案 1 :(得分: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结合使用。