Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用QDialogButtonBox处理程序中止退出对话框?_C++_Qt - Fatal编程技术网

C++ 如何使用QDialogButtonBox处理程序中止退出对话框?

C++ 如何使用QDialogButtonBox处理程序中止退出对话框?,c++,qt,C++,Qt,我的对话框中有QDialogButtonBox按钮,它们是Ok和Cancel按钮对。我已经实现了在按下“确定”按钮时要处理的accepted()信号,但如果目录路径无效,我想中止退出对话框 void SettingsDialog::on_buttonBox_accepted() { QDir path( ui->lineEditRootPath->text() ); if ( path.exists( ui->lineEditRootPath->text

我的对话框中有QDialogButtonBox按钮,它们是
Ok
Cancel
按钮对。我已经实现了在按下“确定”按钮时要处理的accepted()信号,但如果目录路径无效,我想中止退出对话框

void SettingsDialog::on_buttonBox_accepted()
{
    QDir path( ui->lineEditRootPath->text() );

    if ( path.exists( ui->lineEditRootPath->text() ) )
    {
        QSettings settings; // save settings to registry
        settings.setValue(ROOT_PATH, ui->lineEditRootPath->text() );
    }
    else
    {
        // abort cancelling the dialog here
    }
}

是否可以从此处理程序中止对话框退出?我必须在其他信号中实现上述代码吗?我是否必须使用简单按钮来完成此操作,而不是使用
QDialogButtonBox

此问题来自与Qt Creator捆绑的对话框模板。创建带有按钮的空对话框时,
.ui
文件在按钮框和基础对话框之间具有连接。可以说,它们是在你背后创造的:

因此,实际上没有问题,因为按钮框实际上不接受对话框。您必须接受该对话框,如果不接受,则该对话框将保持打开状态

简单的修复方法是删除默认连接


其他挑剔之处 您不应该使用
QDir::exists(const QString&)
重载-它不会工作。您已经提供了dir的构造函数的路径。只需使用
exists()

因此:

您还可以使用静态的
QFileInfo::exists

void SettingsDialog::on_buttonBox_accepted()
{
  if (! QFileInfo.exists(ui->lineEditRootPath->text()) return;
  ...
}
最后,当输入无效时,向用户提供某种反馈可能是个好主意。在C++11中,这很容易做到:

#include <QApplication>
#include <QFileInfo>
#include <QDialog>
#include <QDialogButtonBox>
#include <QLineEdit>
#include <QGridLayout>

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QDialog dialog;
   QLineEdit edit("/");
   QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Close);
   QGridLayout layout(&dialog);
   layout.addWidget(&edit, 0, 0);
   layout.addWidget(&buttons, 1, 0);

   QObject::connect(&buttons, &QDialogButtonBox::accepted, [&]{
      if (!QFileInfo::exists(edit.text())) return;
      //...
      dialog.accept();
   });
   QObject::connect(&buttons, &QDialogButtonBox::rejected, [&]{ dialog.reject(); });

   QObject::connect(&edit, &QLineEdit::textChanged, [&](const QString&){
      if (QFileInfo::exists(edit.text()))
         edit.setStyleSheet("");
      else
         edit.setStyleSheet("* { background: red; }");
   });

   dialog.show();
   return a.exec();
}

这是一个合理的问题,但我可以告诉你,你从来没有尝试过上面的代码。如果你这样做了,你就不会问这个问题了。有时候尝试一下是有帮助的。学习快速编写小型测试用例(就像我的许多答案一样)——它们可以在几分钟内解决此类问题。学习用Qt做实验。这很简单,而且现代C++11 Qt代码与Python等脚本语言一样简洁:)我确实尝试过,对话框在没有调用accept()的情况下被取消,但我会再试一次,并尽快通知您。谢谢你的详细回答。@zadane我已经编辑了答案。对话框被取消,因为您没有审核正在使用的默认模板。那个模板有你们不知道的信号连接。谢谢,很抱歉,你们的回答迟了,我正忙着做别的事情。
#include <QApplication>
#include <QFileInfo>
#include <QDialog>
#include <QDialogButtonBox>
#include <QLineEdit>
#include <QGridLayout>

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QDialog dialog;
   QLineEdit edit("/");
   QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Close);
   QGridLayout layout(&dialog);
   layout.addWidget(&edit, 0, 0);
   layout.addWidget(&buttons, 1, 0);

   QObject::connect(&buttons, &QDialogButtonBox::accepted, [&]{
      if (!QFileInfo::exists(edit.text())) return;
      //...
      dialog.accept();
   });
   QObject::connect(&buttons, &QDialogButtonBox::rejected, [&]{ dialog.reject(); });

   QObject::connect(&edit, &QLineEdit::textChanged, [&](const QString&){
      if (QFileInfo::exists(edit.text()))
         edit.setStyleSheet("");
      else
         edit.setStyleSheet("* { background: red; }");
   });

   dialog.show();
   return a.exec();
}
#include <QApplication>
#include <QFileInfo>
#include <QDialog>
#include <QDialogButtonBox>
#include <QLineEdit>
#include <QPushButton>
#include <QGridLayout>
#include <QThread>
#include <QTimer>

class Thread : public QThread {
   using QThread::run; // final
public:
   ~Thread() { quit(); wait(); }
};

class Checker : public QObject {
   Q_OBJECT
public:
   Q_SIGNAL void exists(bool, const QString & path);
   Q_SLOT void check(const QString & path) { emit exists(QFileInfo::exists(path), path); }
};

int main(int argc, char *argv[])
{
   bool pathExists = true;
   QApplication app(argc, argv);
   QDialog dialog;
   QLineEdit edit("/");
   QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Close);
   QGridLayout layout(&dialog);
   layout.addWidget(&edit, 0, 0);
   layout.addWidget(&buttons, 1, 0);

   QTimer checkTimer;
   Checker checker;
   Thread checkerThread;
   checker.moveToThread(&checkerThread);
   checkerThread.start();
   checkTimer.setInterval(500);
   checkTimer.setSingleShot(true);

   QObject::connect(&buttons, &QDialogButtonBox::accepted, [&]{
      if (!pathExists) return;
      //...
      dialog.accept();
   });
   QObject::connect(&buttons, &QDialogButtonBox::rejected, [&]{ dialog.reject(); });

   QObject::connect(&edit, &QLineEdit::textChanged, &checker, &Checker::check);
   QObject::connect(&edit, &QLineEdit::textChanged, &checkTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
   QObject::connect(&checkTimer, &QTimer::timeout, [&]{ edit.setStyleSheet("background: yellow"); });

   QObject::connect(&checker, &Checker::exists, &app, [&](bool ok, const QString & path){
      if (path != edit.text()) return; // stale result
      checkTimer.stop();
      edit.setStyleSheet(ok ? "" : "background: red");
      buttons.button(QDialogButtonBox::Ok)->setEnabled(ok);
      pathExists = ok;
   });

   dialog.show();
   return app.exec();
}

#include "main.moc"