向 Qt 项目添加状态对话框
Add status dialog to Qt project
我正在制作开源文件管理器,它能够根据给定的名为 Cryptofm 的密码进行加密和解密 file/files。您可以从 here - 第一个版本中获取代码。我想添加状态对话框,代表 Dialog::encAll()
插槽的进度条加载屏幕,在进度条达到最大值后关闭状态对话框。我发现我必须首先递归地找到文件夹中所有文件的总大小(在 TreeView 上下文菜单选项大小中) - 插槽 Dialog::dirSize()
在函数 Dialog::getSelectedTreeItemSize()
的帮助下执行此操作,然后将进度条 属性 最大值设置为该值。总大小计算过程可能会再次花费很多时间,因此我需要另一个对话框,其中包含一些移动的内容以仅指示该过程正在执行。整个过程应该类似于在 Windows 7.
中粘贴包含大量文件的非常大的文件夹的过程
获取总大小的过程:
粘贴到进度条达到总大小的过程:
问题是几乎所有功能、操作等都在对话框中实现 class 而我无法使用线程 - 在 [=41= 中像这样 Dialog : public QDialog, public QThread
添加 QThread 之后](为了能够实现运行()方法)程序给出了一些错误:
C:\Users\niki\Documents\EncryptionProject\dialog.cpp:41: error: C2594:
'argument' : ambiguous conversions from 'Dialog *const ' to 'QObject
*'
C:\Users\niki\Documents\EncryptionProject\dialog.cpp:46: error: C2594:
'argument' : ambiguous conversions from 'Dialog *const ' to 'QObject
*'
C:\Users\niki\Documents\EncryptionProject\dialog.cpp:51: error: C2385:
ambiguous access of 'connect' could be the 'connect' in base 'QObject'
or could be the 'connect' in base 'QObject'
还有 31 个错误,所以:
- 这里最好的选择是什么?
- 我应该使用 MVC 还是其他模式?
- 我应该使用线程吗?
我不明白你的全部问题,但我可以给你一些提示。
错误 "ambiguous conversion" 告诉您 C++ 无法将 Dialog* const
转换为 QObject*
。通常你可以通过使用像 QObject* o = (QObject*) dialog
这样的转换来解决这个问题。您还尝试将指向 const
对象的指针转换为指向非 const
对象的指针。这是不可能的,因为 const
对象不受更改影响,而非 const
对象则不然。尝试删除 const
限定符或将其添加到 QObject*
.
您的第一个屏幕截图中进度条的行为通常称为 "indeterminate mode"。您可以通过将最小值和最大值设置为 0(使用 pbar->setMaximum(0)
和 pbar->setMinimum(0)
)来使用 QProgressBar 实现此行为。
关于你关于线程的问题:是的,你应该使用工作线程来复制文件。使用 UI-线程(您可能在当前解决方案中使用)的问题是,UI 将停止响应用户输入(例如移动 window 或按下按钮) 并且您的 UI 元素(例如 QProgressBar)可能不会更新,因此您的进度对用户不可见。
您以错误的方式将 QThread 添加到您的程序中。您目前从 QDialog(到目前为止一切正常)和 QThread(这就是问题所在)继承了您的自定义 Dialog class。您应该使用 new
创建一个新的 QThread 实例,然后用它调用一个方法,而不是从 QThread 继承。您会在网上找到大量示例。
您可以使用MVC,但在您目前的情况下它只能给您带来一点好处。您也没有 class 逻辑解释中的模型,尽管您可以创建一个处理文件操作的模型。
我做了一些事情。这并不像看起来那么容易。我已经在名为 threadedController 的新 class 中分离了所有执行代码,并使用 moveToThread 将其在 mainWindow 中移动到新线程。重要的是要注意这个 class 继承 QObject 以便能够使用信号槽机制,它在构造函数中没有父对象,因为在其他情况下它不能移动到新线程。 QWidget 对象不能在新线程中移动。 GUI线程和新线程之间的通信似乎可以通过信号槽机制进行。 Qt 使用 Model/View 架构。大家可以去here.
下载第二版源码和exe
我正在制作开源文件管理器,它能够根据给定的名为 Cryptofm 的密码进行加密和解密 file/files。您可以从 here - 第一个版本中获取代码。我想添加状态对话框,代表 Dialog::encAll()
插槽的进度条加载屏幕,在进度条达到最大值后关闭状态对话框。我发现我必须首先递归地找到文件夹中所有文件的总大小(在 TreeView 上下文菜单选项大小中) - 插槽 Dialog::dirSize()
在函数 Dialog::getSelectedTreeItemSize()
的帮助下执行此操作,然后将进度条 属性 最大值设置为该值。总大小计算过程可能会再次花费很多时间,因此我需要另一个对话框,其中包含一些移动的内容以仅指示该过程正在执行。整个过程应该类似于在 Windows 7.
获取总大小的过程:
粘贴到进度条达到总大小的过程:
问题是几乎所有功能、操作等都在对话框中实现 class 而我无法使用线程 - 在 [=41= 中像这样 Dialog : public QDialog, public QThread
添加 QThread 之后](为了能够实现运行()方法)程序给出了一些错误:
C:\Users\niki\Documents\EncryptionProject\dialog.cpp:41: error: C2594: 'argument' : ambiguous conversions from 'Dialog *const ' to 'QObject *'
C:\Users\niki\Documents\EncryptionProject\dialog.cpp:46: error: C2594: 'argument' : ambiguous conversions from 'Dialog *const ' to 'QObject *'
C:\Users\niki\Documents\EncryptionProject\dialog.cpp:51: error: C2385: ambiguous access of 'connect' could be the 'connect' in base 'QObject' or could be the 'connect' in base 'QObject'
还有 31 个错误,所以:
- 这里最好的选择是什么?
- 我应该使用 MVC 还是其他模式?
- 我应该使用线程吗?
我不明白你的全部问题,但我可以给你一些提示。
错误 "ambiguous conversion" 告诉您 C++ 无法将 Dialog* const
转换为 QObject*
。通常你可以通过使用像 QObject* o = (QObject*) dialog
这样的转换来解决这个问题。您还尝试将指向 const
对象的指针转换为指向非 const
对象的指针。这是不可能的,因为 const
对象不受更改影响,而非 const
对象则不然。尝试删除 const
限定符或将其添加到 QObject*
.
您的第一个屏幕截图中进度条的行为通常称为 "indeterminate mode"。您可以通过将最小值和最大值设置为 0(使用 pbar->setMaximum(0)
和 pbar->setMinimum(0)
)来使用 QProgressBar 实现此行为。
关于你关于线程的问题:是的,你应该使用工作线程来复制文件。使用 UI-线程(您可能在当前解决方案中使用)的问题是,UI 将停止响应用户输入(例如移动 window 或按下按钮) 并且您的 UI 元素(例如 QProgressBar)可能不会更新,因此您的进度对用户不可见。
您以错误的方式将 QThread 添加到您的程序中。您目前从 QDialog(到目前为止一切正常)和 QThread(这就是问题所在)继承了您的自定义 Dialog class。您应该使用 new
创建一个新的 QThread 实例,然后用它调用一个方法,而不是从 QThread 继承。您会在网上找到大量示例。
您可以使用MVC,但在您目前的情况下它只能给您带来一点好处。您也没有 class 逻辑解释中的模型,尽管您可以创建一个处理文件操作的模型。
我做了一些事情。这并不像看起来那么容易。我已经在名为 threadedController 的新 class 中分离了所有执行代码,并使用 moveToThread 将其在 mainWindow 中移动到新线程。重要的是要注意这个 class 继承 QObject 以便能够使用信号槽机制,它在构造函数中没有父对象,因为在其他情况下它不能移动到新线程。 QWidget 对象不能在新线程中移动。 GUI线程和新线程之间的通信似乎可以通过信号槽机制进行。 Qt 使用 Model/View 架构。大家可以去here.
下载第二版源码和exe