C++ 如何使用QDialogButtonBox处理程序中止退出对话框?
我的对话框中有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
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"