【问题标题】:Add status dialog to Qt project将状态对话框添加到 Qt 项目
【发布时间】:2016-02-17 06:51:41
【问题描述】:

我正在制作能够根据给定密码 Cryptofm 加密和解密文件/文件的开源文件管理器。您可以从here 获取代码 - 第一个版本。我想添加状态对话框,表示带有Dialog::encAll()插槽的进度条的加载屏幕,在进度条达到最大值后关闭状态对话框。我发现我必须首先递归地找到文件夹中所有文件的总大小(在TreeView上下文菜单选项Size中) - 插槽Dialog::dirSize()是在函数Dialog::getSelectedTreeItemSize()的帮助下做到这一点的,然后设置进度条属性最大值为该值。总大小计算过程可能会再次花费大量时间,因此我需要另一个对话框,其中包含移动内容以指示该过程正在执行。整个过程应该类似于在 Windows 7 中粘贴包含大量文件的超大文件夹的过程。

获取总大小的过程:

进度条达到总大小的粘贴过程:

问题是几乎所有功能、动作等都在 Dialog 类中实现,我无法使用线程 - 在 dialog.h 中添加像这样Dialog : public QDialog, public QThread 这样的 QThread 之后(能够实现 run()方法)程序给出了一些错误:

C:\Users\niki\Documents\EncryptionProject\dialog.cpp:41:错误:C2594: 'argument' : 从 'Dialog *const' 到 'QObject 的模棱两可的转换 *'

C:\Users\niki\Documents\EncryptionProject\dialog.cpp:46:错误:C2594: 'argument' : 从 'Dialog *const' 到 'QObject 的模棱两可的转换 *'

C:\Users\niki\Documents\EncryptionProject\dialog.cpp:51:错误:C2385: “连接”的模糊访问可能是基础“QObject”中的“连接” 或者可能是基础“QObject”中的“连接”

还有 31 个错误,所以:

  • 这里有哪些最佳选择?
  • 我应该使用 MVC 还是其他模式?
  • 我应该使用线程吗?

【问题讨论】:

    标签: c++ qt architectural-patterns


    【解决方案1】:

    我不明白你的全部问题,但我可以给你一些提示。

    “歧义转换”错误告诉您 C++ 无法将 Dialog* const 转换为 QObject*。通常你可以通过使用像QObject* o = (QObject*) dialog 这样的演员来解决这个问题。您还尝试将指向const 对象的指针转换为指向非const 对象的指针。这是不可能的,因为const 对象受到保护,而非const 对象则没有。尝试删除const 限定符或将其添加到QObject*

    第一个屏幕截图中进度条的行为通常称为“不确定模式”。您可以通过将最小值和最大值设置为 0 来使用 QProgressBar 实现此行为(使用 pbar->setMaximum(0)pbar->setMinimum(0))。

    关于线程的问题:是的,您应该使用工作线程来复制文件。使用 UI 线程(您可能在当前解决方案中使用)的问题是,UI 将停止响应用户输入(例如移动窗口或按下按钮),并且您的 QProgressBar 等 UI 元素可能不会更新并且您的进度对用户不可见。 您以错误的方式将 QThread 添加到您的程序中。您目前从 QDialog (到目前为止很好)和 QThread (这就是问题)继承了您的自定义 Dialog 类。您应该使用new 创建一个新的QThread 实例,然后用它调用一个方法,而不是从QThread 继承。你会在网上找到很多例子。

    您可以使用 MVC,但在您当前的情况下它只会给您带来一点好处。尽管您可以创建一个处理文件操作的模型,但您也没有经典解释中的模型。

    【讨论】:

    • statusdialog 是在新线程中运行还是在主线程中(它是模态对话框)?查看插槽 Dialog::dirSize() - 我想运行 statusdialog statusdialog.exec(); 并在运行时在新线程中运行方法 getSelectedTreeItemSize(); 直到它完成,然后设置 pbar->setMaximum(maxVal)pbar->setMinimum(0) 其中 maxVal 是值,返回来自 FUNCTION getSelectedTreeItemSize();.Here 的例子,但是它使用了槽,并且槽不能返回值。
    【解决方案2】:

    我做了一些事情。这并不像看起来那么容易。我已经在名为 threadedController 的新类中分离了所有执行代码,并使用 moveToThread 将其在 mainWindow 中移动到新线程。需要注意的是,这个类继承 QObject 以便能够使用信号槽机制,它在构造函数中没有父级,因为在其他情况下它无法移动到新线程。 QWidget 对象不能在新线程中移动。 GUI线程和新线程之间的通信似乎可以通过信号槽机制进行。 Qt 正在使用模型/视图架构。大家可以从here下载第二版源码和exe。

    【讨论】:

      猜你喜欢
      • 2016-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-27
      • 2010-10-14
      • 1970-01-01
      • 2010-12-05
      相关资源
      最近更新 更多