我看到Qt将一个类放在Ui
接口中,如下所示:
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
...
此方法是否与将整个类封装在命名空间内相同?它当然看起来更清洁。
答案 0 :(得分:9)
不,在您的示例中,Ui::MainWindow
是与全局命名空间中定义的MainWindow
类不同的类。
看哪:
namespace Ui {
class MainWindow;
}
class MainWindow
{
};
int main()
{
Ui::MainWindow mw; // fails due to incomplete type
}
此代码无法编译,因为Ui::MainWindow
是不完整的类型。
最有可能的是,Qt代码只是使用了前向声明。您可以在命名空间中转发声明该类,但您仍然必须在同一命名空间中实际实现该类,否则它不是同一个类。
答案 1 :(得分:1)
两个班级不同。您所谈论的不是Qt,而是使用Designer创建UI对象的结果。 Qt正确地这样做是因为他们试图将生成的代码与您可能添加的任何逻辑分开,例如信号处理函数等等......否则他们必须能够做以下三件事之一:
1)尝试区分设计师需要修改的内容与用户不希望修改的内容之间的区别......以一种他们必须随意提出的神秘方式解决冲突。
2)只需覆盖用户更改的任何内容。
3)如果用户没有删除文件,则不更改文件。
首先是一大堆工作,无论开发人员选择什么,某人,某处都会感到不便。第二种选择当然会让人感到不安,因为他们编写的所有插槽代码都会随着UI的每次更改而被破坏,这几乎在所有时间都非常不方便。由于种种原因,第三种当然不方便。
所以他们所做的就是将Designer生成的UI对象部分与开发人员/用户编写的部分分开。这允许他们简单地销毁对某些明确定义的区域的更改,同时让开发人员添加他们需要的行为而不必继续添加它。
这不是您在常规程序设计中通常会做的事情。它通过这种方式解决了与自动生成的代码有关的相当具体的问题。这是一个相当深思熟虑的方法IMNSHO。
答案 2 :(得分:0)
通常,uic
会生成如下所示的标题:
class Ui_MainWindow
{
// auto-generated stuff
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
}
这使您可以使用MainWindow
作为类的名称,并仍然可以调用自动生成的UI类MainWindow
。请注意,Ui::MainWindow
是完整的类定义,而不是前向声明。