Qt中有哪些功能或概念让你恼火?

Tum*_*oid 17 qt qt4

Qt是一个很好的框架和优秀的UI工具包,它有许多有用的功能和概念.我们大多数人可能都同意,最近诺基亚的奇趣科技公司在开发它方面做得非常好.Qt的最新进展之一是QML,我发现它具有令人着迷的进步.

但是,我发现一些设计糟糕或执行不当的概念,例如模型/视图(概念很好,但实现不是),同样适用于Phonon媒体框架.有人说它的元对象概念让他们发疯.

所有这些显然或多或少都是主观的,但是你在Qt中使用哪些特征或概念令人烦恼或烦恼?你如何绕过它们?

and*_*ref 28

我对Qt的大多数抱怨来自于API并不完全接受QObject提供的动态.如果你敢于创建一个元对象编译器来为C++添加动态行为,为什么还要害羞呢?

我在下面列出的所有内容都是我的团队在某些时候需要的东西,我们必须自己编写代码.这很有趣,我们学到了很多关于Qt内部的知识,但我不介意它是否已经完成并准备好使用.

没有分布式QObject

你知道,就像在Cocoa.他们用QtDBus走了一半 - 唯一剩下的就是网络.我们必须为此实现我们自己的解决方案,因为我们生活在Qt代码之外,我们无法改变内部实现所有不错的功能.

没有用于数据存储的API

当然,每个人都编写自己不完整的QObject-to-SQLite库.不过,QDataStream是一个非常好的开端.

没有数据绑定

好吧,Qt Quick有数据绑定,但数据绑定应该存在于QtCore中.通过良好的数据绑定,编写代表QObject集合的QAbstractItemModel应该是过去的事情:QObjectListModel应该是您所需要的.

(是的,QDataWidgetMapper是个笑话.)

没有QObjects的自动撤消管理

我们的模型类通常是QObjects,Q_PROPERTY有一个可选的NOTIFY信号,它正是实现自动撤销所需要的.这很容易做到应该已经成为Qt的一部分.(但是,它需要一些kludges.)

没有收藏属性

并非所有属性都是平等的.其中一些是收藏品.能够以抽象的方式处理这些将是一件好事.

半生不熟的QMetaStuff API

我只讨厌这个API因为我喜欢它.例如,一个人不能:

  1. 动态构建QMetaObjects并替换它们;
  2. 使用QVariants作为参数调用元方法;
  3. 通过返回类型,名称或参数类型查询方法;
  4. 使用相应的QMetaMethods连接信号和插槽(至少不到4.8);
  5. 例如,截取属性set/get的方式与拦截事件的方式相同.

几乎所有这些都可以轻松解决.#2的解决方案:

QVariant call(QObject* object, QMetaMethod metaMethod, QVariantList args)
{
    QList<QGenericArgument> arguments;

    for (int i = 0; i < args.size(); i++) {

        // Notice that we have to take a reference to the argument. A 
        // const_cast is needed because calling data() would detach 
        // the QVariant.

        QVariant& argument = args[i];

        QGenericArgument genericArgument(
            QMetaType::typeName(argument.userType()),
            const_cast<void*>(argument.constData())
        );

        arguments << genericArgument;
    }

    QVariant returnValue(QMetaType::type(metaMethod.typeName()), 
        static_cast<void*>(NULL));

    QGenericReturnArgument returnArgument(
        metaMethod.typeName(),
        const_cast<void*>(returnValue.constData())
    );

    // Perform the call

    bool ok = metaMethod.invoke(
        object,
        Qt::AutoConnection, // In case the object is in another thread.
        returnArgument,
        arguments.value(0),
        arguments.value(1),
        arguments.value(2),
        arguments.value(3),
        arguments.value(4),
        arguments.value(5),
        arguments.value(6),
        arguments.value(7),
        arguments.value(8),
        arguments.value(9)
    );

    if (!ok) {
        // Handle the error...
    } else {
        return returnValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

有用的功能可能会被删除

有兴趣在qt-interest中讨论将在Qt的未来版本中删除DOM,样式表自定义文件引擎.

Phonon没有跨平台的后端

除了没有真正起作用外,Phonon没有稳定的后端可以在三个最常见的平台上运行:Windows,Linux和Mac OS X.有一个VLC后端,但它肯定不稳定,其许可不清楚而且,VLC对Mac的支持是" 搁置在不稳定的基础上 ".当然,责任完全在Linux上.多媒体支持从未成为 其优势之一.它缺少类似Quicktime或DirectStuff的东西.

没有加密类

有QCryptographicHash和QSSLSocket(及其有趣的错误模式),就是这样.幸运的是,有两个很好的库来填补这个空白:BotanQCA.QCA基于Qt,但是从Java加密类复制其API,所以不是很好.Botan有一个漂亮的界面,(但?)是"纯粹的"C++.Qt风格的加密库仍然缺乏.


Hos*_*ork 11

对于SO来说,这是一个奇怪的问题,但是这里有:

qmake牙齿很长(而且我不是唯一一个这么说的人).我使用cmake,尽管它有自己的尴尬.

信号/插槽/等的元对象预处理构建步骤.是一个巨大的买入.许多愿意接受增加的抽象层次的人是那些被其他环境所吸引的人(Java,C#,无论如何).在围栏的另一边是硬核C++程序员,他们宁愿使用std::thread而不是QThread.

(如果C++程序更加面向服务器并且没有GUI,那么人们似乎避开了Qt,我明白了他们的观点.)

模型/视图既不在这里也不在那里,但它有点微不足道.我批评了线程亲和力的问题:

http://blog.hostilefork.com/qt-model-view-different-threads/

此外,我已经将应用程序交叉编译到Mac,Windows和Linux,并且发现Qt并没有像我希望的那样保护我免受平台问题的影响.如果你看一下内部结构以及如何拖放是极其多样的代码实现(例如qnd_x11.cpp,qdnd_win.cppqdnd_mac.mm)然后就看到了"漏抽象"的原则发挥作用.Qt并没有强加强烈的形式主义; 你会得到不同顺序或重复的消息 - 或者在某些平台上根本没有.

但除了所有批评之外,我确实喜欢Qt的设计,文档,社区支持和一般审美.你可以做得更糟! (我在看着你,wxWidgets和GTK.)


Ale*_*x F 5

我试图解决的问题是Qt,wxWidgets以及可能的其他UI框架的一般问题:

void MainDialog::OnCppException()
{
    throw std::runtime_error("test unhandled exception");
}

Qt框架捕获了这种未处理的C++异常,阻止了立即异常调试或生成信息性崩溃转储.在Qt允许处理这种情况的地方,原始异常信息和堆栈跟踪将丢失.我试图在两个框架中解决这个问题,并没有找到可接受的解决方案.Qt专业人士的建议"就是不要这样做"就是我所拥有的,这实际上意味着:不要犯错误,一切都会好的.这是我对Qt和wxWidjets的最大失望.