Qt初学者:QLineEdit和QTextEdit的基类

除了QWidget之外,还有另外一个类是否拥有两者的所有通用函数?像QEdit ...Qt初学者:QLineEdit和QTextEdit的基类

作为一个例子,我想引用剪切(),复制()和粘贴(),但它看起来像我必须动态铸造QWidget。有没有其他方法?

回答:

QWidget之外没有别的办法。原因是QLineEdit直接从QWidget继承。您可以看到Qt类的完整层次结构here

回答:

您不必动态地施放任何东西:这通常是设计不好的标志。 Qt通常只有很少的接口类 - 它们通常在名称的某个地方有Abstract这个词,而且它们不是纯粹的接口,因为它们有非抽象的基类,例如, QObject。因此没有可遵循的模式,也不需要将编辑操作抽象为接口。

有克服这一几种方法:

  1. 杠杆的事实是有问题的方法是由元对象系统知道。请注意,invokeMethod需要一个方法名称,而不是签名。

    bool cut(QWidget * w) { 

    return QMetaObject::invokeMethod(w, "cut");

    }

    bool copy(QWidget * w) {

    return QMetaObject::invokeMethod(w, "copy");

    }

    //...

    您可以在任何支持编辑操作的窗口小部件上使用上述独立功能,如上所述。

  2. 如上所述,但缓存方法查找不会反复支付其成本。请注意,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);

    }

    //...

  3. 定义一个接口并提供专用于窗口小部件类型的实现。这种方法的唯一好处是它比QMetaMethod::invoke快一点。将此代码用于剪贴板方法是没有意义的,但对于经常调用的小型方法而言,可能会降低开销。我建议不要过度设计它,除非基准测试显示它确实有帮助。以前的方法(上面#2)应该足够。

    // Interface 

    class IClipboard {

    public:

    virtual cut(QWidget *) = 0;

    virtual copy(QWidget *) = 0;

    virtual paste(QWidget *) = 0;

    };

    class Registry {

    // all meta class names have unique addresses - they are effectively memoized

    static QMap<const char *, IClipboard*> registry;

    public:

    static void register(const QMetaObject * o, IClipboard * clipboard) {

    auto name = o->className();

    auto it = registry.find(name);

    if (it == registry.end())

    registry.insert(name, clipboard);

    else

    Q_ASSERT(it->value() == clipboard);

    }

    static IClipboard * for(QWidget * w) {

    auto it = registry.find(w->metaObject()->className());

    Q_ASSERT(registry.end() != it);

    return it->value();

    }

    static void unregister(const QMetaObject * o) {

    registry.remove(o->className());

    }

    };

    template <class W> class ClipboardWidget : public IClipboard {

    Q_DISABLE_COPY(ClipboardWidget)

    public:

    cut(QWidget * w) override { static_cast<W*>(w)->cut(); }

    copy(QWidget * w) override { static_cast<W*>(w)->copy(); }

    paste(QWidget * w) override { static_cast<W*>(w)->paste(); }

    ClipboardWidget() {

    Registry::register(&W::staticMetaObject(), this);

    }

    ~ClipboardWidget() {

    Registry::unregister(&W::staticMetaObject());

    }

    };

    // Implementation

    QMap<const char *, IClipboard*> Registry::registry;

    static ClipboardWidget<QTextEdit> w1;

    static ClipboardWidget<QLineEdit> w2;

    void yourCode() {

    //...

    Registry::for(widget)->cut(widget);

    }

以上是 Qt初学者:QLineEdit和QTextEdit的基类 的全部内容, 来源链接: utcz.com/qa/260984.html

回到顶部