【问题标题】:QFileDialog opens in new window while adding it to QHBoxLayoutQFileDialog 在新窗口中打开,同时将其添加到 QHBoxLayout
【发布时间】:2017-08-21 20:20:25
【问题描述】:

我的问题是,当我将 QFileDialog 添加到 QVBoxLayout 时,它会在新窗口中打开。下面是产生我的问题的代码。

from PyQt5.QtWidgets import QVBoxLayout, QFileDialog, QPushButton, QWidget


class MainWindow(QtWidgets.QWidget):
    def __init__(self):
       super(MainWindow, self).__init__()
       self.setWindowTitle("My own MainWindow")

       self.fileDialog = QFileDialog()

       self.confirmAction = QPushButton("Press me", self)

       mainLayout = QVBoxLayout()

       mainLayout.addWidget(self.fileDialog)
       mainLayout.addWidget(self.confirmAction)
       self.setLayout(mainLayout)

【问题讨论】:

  • QFileDialog继承自QDialog,这些元素都是用来创建对话窗口的,所以显示是正确的。你可以解释你想得到什么。
  • 我想在 QVBoxLayout QFileDialog 中作为第一项,并作为 QFileDialog 下面的第二项简单 QPushButton。
  • 我的直接问题是:为什么要在 Widget 中嵌入 QFileDialog?
  • 仅出于培训目的,我想制作这样的小部件,它包含 QFileDialog 和 QPushButton 以下。
  • 试试我的答案,如果我能帮助你,别忘了把它标记为正确。

标签: python pyqt pyqt5 qdialog


【解决方案1】:

根据docs

窗口标志是类型(例如 Qt::Dialog)和零或 对窗口系统的更多提示(例如 Qt::FramelessWindowHint)。

如果小部件的类型为 Qt::Widget 或 Qt::SubWindow 并成为 窗口(Qt::Window、Qt::Dialog 等),它被放在位置 (0, 0) 上 桌面。如果小部件是一个窗口并变成一个 Qt::Widget 或 Qt::SubWindow,它被放置在相对于其父级的位置 (0, 0) 小部件。

因此,这些标志用于改变小部件的行为,例如将其转换为窗口、对话框、工具提示等。

docs中给出了以下列表:

Qt::Widget:这是默认的 QWidget 的类型。这种类型的小部件是子小部件,如果它们有 一个父窗口,如果它们没有父窗口,则为独立窗口。也可以看看 Qt::Window 和 Qt::SubWindow。

Qt::Window:表示 小部件是一个窗口,通常带有一个窗口系统框架和一个标题 栏,无论小部件是否有父级。注意 如果小部件没有 父母。

Qt::Dialog :Window 表示小部件是一个 应装饰为对话框的窗口(即,通常没有 标题栏中的最大化或最小化按钮)。这是默认设置 QDialog 的类型。如果你想把它用作一个模态对话框,它应该 从另一个窗口启动,或者有一个父窗口并与 QWidget::windowModality 属性。如果将其设为模态,则对话框 将阻止应用程序中的其他顶级窗口获取 任何输入。我们将具有父级的顶级窗口称为 辅助窗口。

Qt::Sheet: Window 表示 window 是一个 Macintosh 工作表。由于使用工作表意味着窗口 模态,推荐的方式是使用QWidget::setWindowModality(), 或 QDialog::open(),而不是。

Qt::Drawer:窗口表示 该小部件是 Macintosh 抽屉。

Qt::Popup : Window 表示小部件是弹出式顶层窗口,即 它是模态的,但有一个适合弹出窗口的窗口系统框架 菜单。

Qt::Tool: Window 表示这个小部件是一个 工具窗口。工具窗口通常是一个小于 常用的标题栏和装饰,通常用于工具的集合 纽扣。如果有父级,工具窗口将始终保持打开 最重要的是。如果没有父母,您可以考虑使用 Qt::WindowStaysOnTopHint 也是如此。如果窗口系统支持它,一个 工具窗口可以用较轻的框架装饰。它可以 也可以与 Qt::FramelessWindowHint 结合使用。

在 Mac OS X 上,工具窗口对应于 Floating 类窗口。 这意味着窗口位于普通窗口之上;它 不可能在它上面放一个普通的窗口。默认情况下,工具 当应用程序处于非活动状态时,窗口将消失。这可以是 由 Qt::WA_MacAlwaysShowToolWindow 属性控制。

Qt::ToolTip:Window 表示小部件是一个 工具提示。这在内部用于实现工具提示。

Qt::SplashScreen: Window 表示窗口是一个 闪屏。这是 QSplashScreen 的默认类型。

Qt::Desktop:Window 表示这个小部件是 桌面。这是 QDesktopWidget 的类型。

Qt::SubWindow:表示这个widget是一个子窗口, 例如 QMdiSubWindow 小部件。

在您的情况下,我们必须将Qt::Dialog 的行为更改为Qt::Widget,在下面的代码中,我展示了执行此操作的代码:

class MainWindow(QWidget):
    def __init__(self):
       super(MainWindow, self).__init__()
       self.setWindowTitle("My own MainWindow")

       self.fileDialog = QFileDialog(self)
       self.fileDialog.setOption(QFileDialog.DontUseNativeDialog)
       self.fileDialog.setWindowFlags(Qt.Widget)

       self.confirmAction = QPushButton("Press me", self)

       mainLayout = QVBoxLayout()

       mainLayout.addWidget(self.fileDialog)
       mainLayout.addWidget(self.confirmAction)
       self.setLayout(mainLayout)

截图:

【讨论】:

  • 现在很清楚了,但是你做了哪个导入来拥有 Qt.Widget?
  • 当然,我会这样做。感谢您澄清我的问题。
  • 在单独的文件中,我正在创建小部件并使用 w = MainWindow() w.show() 显示它
  • 完整的例子可以在这里找到:gist.github.com/eyllanesc/7cf200538e182b5662552700c27b998a,下载并运行它,另外如果你发现我已经传递给self作为@987654330的parent @
  • gist 中的代码有效,但前提是它不使用所谓的本机对话框。在 Linux 上,这意味着您不应在 KDE 会话或安装了 Qt 集成插件的任何其他会话下“按原样”运行它。在显示对话框之前添加self.fileDialog.setOption(QFileDialog.DontUseNativeDialog),它将一直有效。
【解决方案2】:

我自己一直在研究这个问题,对“只使用非本地对话框”这一点不满意。我一直在研究 KDE 平台文件对话框的实现,并且已经(卡住)非常接近我想要的。

我发现的唯一附加点是在对话框实际显示之前;在此之前似乎没有办法知道实际的父小部件。但我们可以:

  • 找到父QWidget(从父QWindow
  • 从中获取(第一个)(用户端)QFileDialog 实例
  • 如果父QWidget有布局,用我们自己的对话框替换找到的QFileDialog实例
  • 保存原用户端QFileDialog实例
  • 在 dtor 中,要么恢复布局中的原始 QFD,要么对其调用 deleteLater()(并将其设置为 NULL,以防操作导致递归调用 dtor)。

故障: - 对话框可能以 2 组 OK/Cancel/etc 结束。纽扣 - 如果不是,这些按钮实际上可能只关闭嵌入式 QFD 而不是封闭对话框(参见上面链接的 python 示例) - 调整大小有效,但 saveSize/restoreSize 机制无效 - AFAICT 所有信号未正确连接(Scribus 打开文件对话框中的预览不会对选择文件做出应有的反应)。文件打开确实有效。

此 BKO 门票的完整补丁: https://bugs.kde.org/show_bug.cgi?id=404833#c15

显然,这仅对可以发布自己的平台主题插件(这是 KDE 平台文件对话框的来源)的黑客和软件有用。幸运的是,这些插件往往相对较小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-01
    • 2012-04-12
    • 2014-03-24
    • 2021-10-24
    • 2017-03-08
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    相关资源
    最近更新 更多