简体   繁体   English

如何从 QList 迭代 qobject_cast 项目

[英]How to iteratively qobject_cast items from a QList

I was trying out the "echo plugin" from the qt examples and i changed somethings to try out and stumbled upon an error that i cant fix.我正在尝试 qt 示例中的“echo 插件”,我更改了一些东西来尝试并偶然发现一个我无法修复的错误。 here is the original Echo Window class这是原来的 Echo Window class

#include <QWidget>
#include "echointerface.h"
QT_BEGIN_NAMESPACE
class QString;
class QLineEdit;
class QLabel;
class QPushButton;
class QGridLayout;
QT_END_NAMESPACE

//! [0]
class EchoWindow : public QWidget
{
    Q_OBJECT

public:
    EchoWindow();

private slots:
    void sendEcho();

private:
    void createGUI();
    bool loadPlugin();

    EchoInterface *echoInterface;  ***********
    QLineEdit *lineEdit;
    QLabel *label;
    QPushButton *button;
    QGridLayout *layout;

};

what i changed is the the line i highlighted with the stars.我改变的是我用星星突出显示的那一行。 i changed it into A Qlist like this我把它改成了这样的Qlist

QList<EchoInterface *>echoInterfaces 

also changed the implementation of the function LoadPlugin() From this:-还更改了 function LoadPlugin() 的实现从此:-

bool EchoWindow::loadPlugin()
{
    QDir pluginsDir(qApp->applicationDirPath());
    pluginsDir.cd("plugins");
    foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject *plugin = pluginLoader.instance();
        if (plugin) {
            echoInterface = qobject_cast<EchoInterface *>(plugin);
            if (echoInterface)
                return true;
        }
    }

    return false;
}

To this:-对此:-

    bool ModifyWindow::loadPlugin()
{
    QDir pluginsDir(qApp->applicationDirPath());
    pluginsDir.cd("plugins");
    foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject *plugin = pluginLoader.instance();
        if (plugin) {
            foreach ( EchoInterface *a, echoInterfaces)
            {
               a = qobject_cast <EchoInterface *>(plugin);
            }
                if(!echoInterfaces.contains(NULL))
                    return true;
            }

        }
    return false;
}

and thanks in advance并提前致谢

If my guess is correct, you'd like to store a collection of interfaces and your question is about how to read it properly.如果我的猜测是正确的,你想存储一个接口集合,你的问题是关于如何正确读取它。 I do understand that我明白

assumption is the mother of all screw-ups假设是所有错误之母

:) But let's not focus on the reason for doing this and just guess (again) that the EchoInterface is a base class for a variety of some available interfaces. :) 但是我们不要关注这样做的原因,只是(再次)猜测EchoInterface是一些可用接口的基础 class。

What's wrong in your code:你的代码有什么问题:

bool ModifyWindow::loadPlugin()
{
    QDir pluginsDir(qApp->applicationDirPath());
    pluginsDir.cd("plugins");
    foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject *plugin = pluginLoader.instance();
        if (plugin) {
            foreach ( EchoInterface *a, echoInterfaces)
            {
               // this is pointless - only a tmp variable 'a' is modified for a while
               // just to be reset on the next iteration
               a = qobject_cast <EchoInterface *>(plugin);
            }
                if(!echoInterfaces.contains(NULL)) // use nullptr instead of NULL 
                    return true; // echoInterfaces is always empty, so it doesnt contain null
            }

        }
    return false;
}

The changes you're loking for:您正在寻找的变化:

bool EchoWindow::loadPlugin()
{
    QDir pluginsDir(QCoreApplication::applicationDirPath());
    pluginsDir.cd("plugins");
    const QStringList entries = pluginsDir.entryList(QDir::Files);
    for (const QString &fileName : entries) {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject *plugin = pluginLoader.instance();
        // it's unnecessary to check if plugin == nullptr,
        // because in this case qobject_cast returns nullptr
        // and we go directly to pluginLoader.unload();
        if (EchoInterface * echoIface = qobject_cast<EchoInterface *>(plugin)) {
            echoInterfaces.append(echoIface); // populate the collection with a valid pointer
            continue; // to avoid the pluginLoader.unload() call which would destroy the echoIface
        }
        pluginLoader.unload();
    }

    // Since we ensured that the echoInterfaces can contain only valid pointers,
    // no additional checks are necessary — the fact that something is stored in the collection is enough
    return !echoInterfaces.isEmpty();

    // or
    // return echoInterfaces.size() > 0;
    // or even just
    // return echoInterfaces.size();
}

In case my assumptions were wrong, then we definitely need a more detailed question.如果我的假设是错误的,那么我们肯定需要一个更详细的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM