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

由于 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 时无法启用/禁用菜单。Signal 正在按顺序调用插槽,因此当您尝试禁用菜单时 QAction 很忙。试试这个:

  1. 在主屏幕中,使用一个启用/禁用菜单栏的布尔参数创建一个插槽。只需调用 setEnabled 函数
  2. 在 ViPro_Dialog 中,发出带有布尔参数的信号(启动时为假,验证时为真)
  3. 在 Create_ViPro 中,创建对话框后,将新信号与插槽连接,执行对话框,不要忘记断开插槽与信号的连接:

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

// 连接信号/槽

模态的.show(); modal.exec(); // 将一直留在这里,直到您关闭模态对话框

// 断开信号/槽 }

这可以达到你想要的

编辑2

您在使用模态对话框时犯了一个错误。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 回答
0

Usingexec()不仅创建了一个模态对话框,它还暂停了大部分常规事件处理,并且只处理exec(). 这可能包括一些 UI 更新(例如从启用到禁用的转换),但我并不肯定。处理此问题的更好方法可能是显式设置对话框模式,但允许常规事件循环继续,如下所示:

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

该代码仍不会在视觉上禁用工具栏或菜单栏,但它们应该没有响应。要禁用它们,您可以尝试将其与Patrice Bernassola 的答案结合使用。

于 2012-04-17T18:14:49.547 回答