Qt新手:QLineEdit和QTextEdit的基类
除了Qt新手:QLineEdit和QTextEdit的基类,qt,qwidget,Qt,Qwidget,除了QWidget之外,还有另一个类保存这两个类的所有通用函数吗?像QEdit之类的东西 作为一个例子,我想引用cut()、copy()和paste(),但看起来我必须动态转换QWidget。还有别的办法吗?除了QWidget之外,没有别的办法了。原因是QLineEdit直接从QWidget继承。您可以看到Qt类的完整层次结构除了QWidget之外,没有其他方法。原因是QLineEdit直接从QWidget继承。您可以看到Qt类的完整层次结构,您不必动态强制转换任何内容:这通常是糟糕设计的标志。
QWidget
之外,还有另一个类保存这两个类的所有通用函数吗?像QEdit之类的东西
作为一个例子,我想引用cut()、copy()和paste(),但看起来我必须动态转换
QWidget
。还有别的办法吗?除了QWidget
之外,没有别的办法了。原因是QLineEdit
直接从QWidget
继承。您可以看到Qt类的完整层次结构除了QWidget
之外,没有其他方法。原因是QLineEdit
直接从QWidget
继承。您可以看到Qt类的完整层次结构,您不必动态强制转换任何内容:这通常是糟糕设计的标志。Qt通常只有很少的接口类-它们通常在名称中的某个地方有单词Abstract
,并且不是真正的纯接口,因为它们有非抽象基类,例如QObject
。因此,不需要遵循任何模式,也不需要将编辑操作抽象到接口中
有几种方法可以克服这一问题:
invokeMethod
采用的是方法名,而不是签名
bool cut(QWidget * w) {
return QMetaObject::invokeMethod(w, "cut");
}
bool copy(QWidget * w) {
return QMetaObject::invokeMethod(w, "copy");
}
//...
您可以在支持编辑操作的任何小部件上使用上述独立功能indexOfMethod
采用方法签名,而不仅仅是其名称
static QMetaMethod lookup(QMetaObject * o, const char * signature) {
return o->method(o->indexOfMethod(signature));
}
struct Methods {
QMetaMethod cut, copy;
Methods() {}
explicit Methods(QMetaObject * o) :
cut(lookup(o, "cut()")),
copy(lookup(o, "copy()")) {}
Methods(const Methods &) = default;
};
// Meta class names have unique addresses - they are effectively memoized.
// Dynamic metaobjects are an exception we can safely ignore here.
static QMap<const char *, Methods> map;
static const Methods & lookup(QWidget * w) {
auto o = w->metaObject();
auto it = map.find(o->className());
if (it == map.end())
it = map.insert(o->className(), Methods(o));
return *it;
}
bool cut(QWidget * w) {
lookup(w).cut.invoke(w);
}
bool copy(QWidget * w) {
lookup(w).copy.invoke(w);
}
//...
您不必动态强制转换任何内容:这通常是糟糕设计的标志。Qt通常只有很少的接口类-它们通常在名称中的某个地方有单词
Abstract
,并且不是真正的纯接口,因为它们有非抽象基类,例如QObject
。因此,不需要遵循任何模式,也不需要将编辑操作抽象到接口中
有几种方法可以克服这一问题:
invokeMethod
采用的是方法名,而不是签名
bool cut(QWidget * w) {
return QMetaObject::invokeMethod(w, "cut");
}
bool copy(QWidget * w) {
return QMetaObject::invokeMethod(w, "copy");
}
//...
您可以在支持编辑操作的任何小部件上使用上述独立功能indexOfMethod
采用方法签名,而不仅仅是其名称
static QMetaMethod lookup(QMetaObject * o, const char * signature) {
return o->method(o->indexOfMethod(signature));
}
struct Methods {
QMetaMethod cut, copy;
Methods() {}
explicit Methods(QMetaObject * o) :
cut(lookup(o, "cut()")),
copy(lookup(o, "copy()")) {}
Methods(const Methods &) = default;
};
// Meta class names have unique addresses - they are effectively memoized.
// Dynamic metaobjects are an exception we can safely ignore here.
static QMap<const char *, Methods> map;
static const Methods & lookup(QWidget * w) {
auto o = w->metaObject();
auto it = map.find(o->className());
if (it == map.end())
it = map.insert(o->className(), Methods(o));
return *it;
}
bool cut(QWidget * w) {
lookup(w).cut.invoke(w);
}
bool copy(QWidget * w) {
lookup(w).copy.invoke(w);
}
//...
你的问题不清楚,请更好地解释自己。你对动态演员阵容有什么问题?(在Qt中,您应该使用哪个
qobject\u cast
)您的问题不清楚,请更好地解释自己。动态cast有什么问题?(在Qt中,您应该使用qobject\u cast
)谢谢。但这让我想知道他们为什么这样做?那些cut()、copy()、paste()和canPaste()函数以及可能更多的函数可以在基类中设置,这两个函数可以从基类中继承。@Igor这里我们只能猜测。这些函数对于Qt架构师来说似乎并不那么重要。他们更多地考虑了QFraseBasic类<代码> QWIDGET < /Case> ISA<代码> QObjult,这使得它比原始C++更强大,因为内省:谢谢。但这让我想知道他们为什么这样做?那些cut()、copy()、paste()和canPaste()函数以及可能更多的函数可以在基类中设置,这两个函数可以从基类中继承。@Igor这里我们只能猜测。这些函数对于Qt架构师来说似乎并不那么重要。他们更多地考虑QFraskBaseBase<代码> QWIDGET < /Case> ISA<代码> QObjult,这使得它比原始的C++类型更强大,因为内省: