繁体   English   中英

QFileDialog:强制文件名

[英]QFileDialog: force file name

我想创建一个QFileDialog设置为QFileDialog::AnyFile ,其中文件名是固定的(但位置可以更改)。

到目前为止,我发现了问题QFileDialog - Saving a file with specified file name ,没有得到回答。
有直接选择目录的伪答案,这是我迄今为止在我的项目中所做的。 然而,通过人们测试该程序,发现这令人困惑,因此不是一个可接受的答案。

到目前为止,我尝试的是派生QFileDialog然后强制执行此操作,但我不知道该尝试什么了。 当点击不同的文件时,我设法通过对适当的信号做出反应来重置文件名:

FixedFileDialog::FixedFileDialog(QWidget* parent) : QFileDialog(parent)
{
    connect(this, SIGNAL(currentUrlChanged(const QString&)), this, SLOT(current_changed(const QString&)));
}

void FixedFileDialog::current_changed(const QString&)
{
    selectFile(_filename);
}

(以_filename为开头的成员集。)

到目前为止,这有效,但它不会阻止用户在行编辑中输入不同的名称。 而且我还没有发现在这种情况下发出的任何信号。

另一种尝试是尝试访问QLineEdit小部件本身以禁用它,但我不知道如何。 我试过了

QLineEdit* line_edit = dialog.d_func()->lineEdit();

dialog是派生的 class。)

这不起作用,因为d_func()QFileDialog中是私有的。

有人有其他想法该怎么做吗?

我必须承认,我想到的是一个肮脏的黑客。 另一方面,OP对我来说似乎有些绝望。 所以,我把它贴出来(带着一些疑问)。

由于OP的声明,我提出了我的想法:

QLineEdit* line_edit = dialog.d_func()->lineEdit();

(对话框是派生的 class。)

这不起作用,因为d_func()QFileDialog中是私有的。

虽然d_func()是私有的,但 Qt 小部件提供了一种后门,因为它们的所有权管理可以被利用:

每个QObject都提供一个其子对象的列表。 因此,对这个子树的简单遍历应该在 quest 中传递QLineEdit (这是我在 Qt 5.13 中QFileDialog的当前实现中唯一的一个)。

这是我在示例中尝试的:

/ Qt header:
#include <QtWidgets>

QLineEdit* findFirstQLineEdit(QWidget *pQWidget)
{
  //qDebug() << "Inspect" << pQWidget;
  const QObjectList pQObjs = pQWidget->children();
  for (QObject *pQObj : pQObjs) {
    if (QLineEdit *pQLineEdit = dynamic_cast<QLineEdit*>(pQObj)) {
      qDebug() << "Found:" << pQLineEdit;
      return pQLineEdit;
    } else if (QWidget *pQWidget = dynamic_cast<QWidget*>(pQObj)) {
      if (QLineEdit *pQLineEdit = findFirstQLineEdit(pQWidget)) {
        return pQLineEdit;
      }
    }
  }
  return nullptr;
}

// main application
int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  QFileDialog qFileDlg(nullptr,
    QString::fromUtf8("Choose Dir. to Save File"),
    QDir::currentPath());
  qFileDlg.show();
  // manipulate the file name input
  qFileDlg.selectFile("CMakeLists.txt");
  QLineEdit *const pQEdit = findFirstQLineEdit(&qFileDlg);
  pQEdit->setReadOnly(true);
  // runtime loop
  return app.exec();
}

Output:

testQFileDialogQLineEditReadOnly 的快照

文件名行编辑器是只读的。 不允许编辑或删除,但仍可以从外部复制和更改内容。 (对于这种情况,OP 似乎已经找到了另一种解决方案。)

笔记:

我的第一个想法是在派生自QFileDialog的 class 的构造函数中调用findFirstQLineEdit() 这没有用! 调试 output 证明QFileDialog构造后没有任何子级。 我得出的结论是, QFileDialog的子项是稍后创建的——但肯定必须在show()之后创建。

要将这个 hack 嵌入到派生的 class 中,在QFileDialog::showEvent()的覆盖中进行操作可能就足够了。 (我没有测试它。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM