簡體   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