Qt的内部课程 [英] Inner classes in Qt
问题描述
我正在将Qt5与VS2013编译器一起使用.我试图将两个类CUDial
和DUDial
嵌套在同一外部类UDial
中.
I am using Qt5 with the VS2013 compiler. I am trying to nest two classes CUDial
and DUDial
in the same outer class UDial
.
UDial
是QDialog
类型的类.我希望CUDial
和DUDial
均为QWidget
类型.它与外部类中的QTabWidget
变量一起使用.
UDial
is a QDialog
type class. I would like CUDial
and DUDial
to be both of QWidget
type. It for use with a QTabWidget
variable in the outer class.
因此,我将代码编写如下:
So, I write the code as follow:
class UDial : public QDialog
{
Q_OBJECT
class CUDial : public QWidget
{
Q_OBJECT
// Some variables
public:
CUDial(QWidget *parent = 0);
}wid1;
class DUDial : public QWidget
{
Q_OBJECT
// Some variables
public:
DUDial(QWidget *parent = 0);
}wid2;
QTabWidget *tab;
QDialogButtonBox *box;
QVBoxLayout *vlay;
public:
UDial(QWidget *parent = 0);
};
实现代码后,我尝试编译并出现以下C2664错误:
After I implemented the code, I tried to compiled and got the following C2664 error:
错误:C2664:'int QTabWidget :: addTab(QWidget *,const QIcon&,const QString&)':无法将参数1从'UDial :: CUDial'转换为'QWidget *'
error: C2664: 'int QTabWidget::addTab(QWidget *,const QIcon &,const QString &)' : cannot convert argument 1 from 'UDial::CUDial' to 'QWidget *'
没有可用的用户定义的转换运算符可以执行此转换,否则无法调用该运算符
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
我想这是嵌套类的QWidget
继承问题.
I guess that it is a problem with the QWidget
inheritance of my nested classes.
有没有办法解决这个问题?
Is there a way I can solve that issue?
推荐答案
在评论中进行了一些讨论之后,我承认我鼓励此处采用的方法基于一点意见,因此,我强烈建议阅读此问题下的所有答案.但是,请务必在此答案中注意该段落的粗体字.
After some discussions in the comments I admit the approach I encourage here is a bit opinion based, so I strongly advise to read all answers under this question. However, please do note the paragraph with statements in bold in this answer.
通常,按照Qt从文档的建议:
In general, following Qt's suggestion from the documentation:
QObjects在对象树中进行组织.当您创建带有另一个对象作为父对象的QObject时,它会添加到父对象的children()列表中,并在父对象被删除时被删除.事实证明,这种方法非常适合GUI对象的需求.例如,QShortcut(键盘快捷方式)是相关窗口的子级,因此当用户关闭该窗口时,快捷方式也会被删除.
QObjects organize themselves in object trees. When you create a QObject with another object as parent, it's added to the parent's children() list, and is deleted when the parent is. It turns out that this approach fits the needs of GUI objects very well. For example, a QShortcut (keyboard shortcut) is a child of the relevant window, so when the user closes that window, the shortcut is deleted too.
不应按值保存QWidget
类型的实例,因为将它们添加到QTabWidget
时,它将成为它们的父级,并会在解构时尝试删除它们.
you should not hold instances of QWidget
types by value, because when adding them to QTabWidget
it will become their parent and will attempt to delete them on deconstruction.
The problem lies in the fact that you are passing an object by value (wid1
) to a function which requires a pointer (QTabWidget::addTab
). Usually you can just change it to &wid1
but it can cause problems in the aforementioned context of Qt's memory management.
在您的特定情况下,它可以正常工作,因为销毁将在您的类中开始,删除其成员,并且它们将正确地从QTabWidget
注销,因此以后不会尝试再次删除它们.
In your particular case, it will work fine, because the destruction will start in your class, deleting its members, and they will correctly unregister from QTabWidget
, so it won't attempt to delete them again later.
但是,这可能会导致代码结构不灵活-如Qt文档链接页中所述,其中简单的对象构造重新排序会导致崩溃.
This however can lead to an inflexible code structure - as explained in the linked page of Qt's documentation, where simple reordering of object construction leads to a crash.
此外,您将需要手动重新排列类中的成员,以随着代码的发展而遵循它们的依赖关系.如果您不必这样做,这似乎很愚蠢:Qt可以很好地管理窗口小部件的生命周期,并且您不必为此担心.
Also, you will need to manually reorder the members inside your class, to follow their dependencies as your code evolves. This seems silly, if you don't have to do it: Qt will do just fine managing the life-time of your widgets, and you don't have to worry about it.
因此,最安全的解决方案是拥有一个指针CUDial* wid1
,将其分配给new
,然后让QTabWidget
管理其寿命.
Thus, the safest solution is to have a pointer CUDial* wid1
, allocate it with new
and let QTabWidget
manage its life-time.
这篇关于Qt的内部课程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!