使用Qt创建运行更快的应用程序

Create Your Apps Faster With Qt

使用Qt创建运行更快的应用程序

Tuesday January 25, 2022 by Peter Schneider | Comments

​2022年1月25日星期二 Peter Schneider | 评论

If you could create your app in 5 instead of 6 months, would it matter? If you could build the first prototype within 4 hours instead of one week, would it matter?

如果你能在5个月而不是6个月内创建应用程序,这有关系吗?如果你能在4小时内而不是一周内制造出第一个原型,这有关系吗?

We as Product Managers always have had three dimensions to play with when steering a software development project: Scope, Time, and Quality. The number of developers is most of the time fixed for multiple reasons. The amount of quality issues customers are willing to tolerate is limited. That leaves us typically with two dimensions to manage the expectations of management and customers: Scope and Time. But there is another way to increase R&D velocity without cutting down the Minimum Viable Product to a bare minimum.

作为产品经理,我们在指导软件开发项目时总是要考虑三个方面:范围、时间和质量。由于多种原因,开发人员的数量在大多数情况下是固定的。客户愿意容忍的质量问题数量有限。这让我们通常有两个维度来管理管理层和客户的期望:范围和时间。但还有另一种方法可以提高研发速度,而不必将最低可行产品削减到最低限度。

You might be wondering if you already squeezed everything out of your product creation workflow. I might have a suggestion for you if you are looking beyond agile methodologies, automated unit testing, and continuous deployment to optimize R&D efficiency:
Switch to an Integrated Software Development Platform which breaks up organizational silos. Switch your UI framework to a Cross-Platform framework that brings Designers, Technical Artists, Software Developers, and Testers together as one team. Bringing these people together as one team working on one codebase removes waste in every single development iteration and improves, therefore, your time to market. Let me give you an example:

你可能会想,你是否已经从你的产品创建工作流程中挤出了一切。如果您的目光超越了敏捷方法、自动化单元测试和持续部署来优化研发效率,我可能会给您一个建议:
切换到一个集成的软件开发平台,打破组织的孤立。将您的UI框架切换到跨平台框架,将设计师、技术艺术家、软件开发人员和测试人员作为一个团队聚集在一起。将这些人聚集在一起,组成一个团队,在一个代码库上工作,可以消除每次开发迭代中的浪费,从而缩短上市时间。我举个例子:

In my previous job, I used to be the Product Manager of a B2B cloud solution. Every time we added a major feature, the UI Designers – having interpreted my ugly hand-drawn sketch of what customers wanted – came up first with a wireframe and then in another iteration with the visual design. Once a handful of strategic customers gave their input to the first visual design, the UI Designer reiterated the design and then gave their work product to the software developer. The work product of the UI Designer was a PDF file or a PNG image. The Front-End Developer had to start from scratch to implement a functional UI.

在我之前的工作中,我曾是B2B云解决方案的产品经理。每次我们添加一个主要功能时,用户界面设计师——在解释了我那丑陋的手绘草图之后——首先提出了一个线框,然后在另一次迭代中提出了视觉设计。一旦少数战略客户为第一个视觉设计提供了意见,UI设计师就重申了设计,然后将他们的工作产品交给了软件开发人员。UI设计器的工作产品是PDF文件或PNG图像。前端开发人员必须从头开始实现功能性UI。

Once the Front-End Developer had built the first functional UI, it did resemble somehow the visual design of the UI Designer, but it was still rather rough because “the CSS styling can be done towards the end” I was told more than once. With the functional UI, we went then back to the customers and asked for their feedback which led to another iteration of UI design and UI implementation, both with zero synergies.

一旦前端开发人员构建了第一个功能性UI,它确实在某种程度上类似于UI设计师的视觉设计,但它仍然相当粗糙,因为我不止一次被告知“CSS样式可以在最后完成”。有了功能性的UI,我们又回到客户那里,询问他们的反馈,这导致了UI设计和UI实现的另一次迭代,两者都没有协同效应。

Illustration: Traditional Product Creation Workflow

插图:传统的产品创建工作流

A lot of waste was produced because the Front-End Developer did have to start always from zero code to create the new version of the UI. With every iteration, the UI Designer created “impressions” of the visual design but nothing tangible, at least from the point of view of the Front-End or UI Developer. Designers and Developers worked in their own silos and I as a Product Manager tried to “glue” things together. Not to mention that the UI Designer was a freelancer and with every iteration she created more billable hours for herself, but that is another story…

产生了大量浪费,因为前端开发人员必须始终从零代码开始创建新版本的UI。在每次迭代中,UI设计师都会对视觉设计产生“印象”,但没有任何有形的东西,至少从前端或UI开发人员的角度来看是这样。设计师和开发人员在各自的筒仓中工作,而我作为产品经理,试图将这些东西“粘合”在一起。更不用说UI设计师是一名自由职业者,每次迭代她都会为自己创造更多的计费时间,但这是另一回事了…

I wish there would have been a better way to work. I know now that there is, at least when one builds the application with C++ or Python (I was working with Angular in the front-end and Java in the back-end).

我希望有更好的工作方式。我现在知道,至少有一个用C++或Python构建应用程序(我在前端使用Angular,后端使用java)。

An Integrated Software Development Platform like Qt removes the barriers between Visual Designers and Front-End or UI Developers. While UI Designers can stick to their preferred UI Design tool such as Figma or Adobe XD, Integrated Software Development Platforms allow Front-End Developers to import the UI designs and create automatically working code. Tools like the Qt Design Studio allow Front-end Developers to import UI assets and compose a functional User Interface. Instead of starting from no code, Qt Design Studio creates usable assets during the import and even readable software code.

​像Qt这样的集成软件开发平台消除了视觉设计师和前端或UI开发人员之间的障碍。虽然UI设计师可以坚持使用他们喜欢的UI设计工具,如Figma或Adobe XD,但集成软件开发平台允许前端开发人员导入UI设计并自动创建工作代码。Qt Design Studio等工具允许前端开发人员导入UI资产并组成功能性用户界面。Qt Design Studio不是从没有代码开始,而是在导入过程中创建可用资产,甚至创建可读的软件代码。

The functional UI code can then be immediately modified in the Qt Design Studio itself, always with a visual editor and a live preview of what the UI will look like. And breaking up silos doesn’t stop here. Back-end developers can take the code created from the Qt Design Studio directly into the Qt Creator, an Integrated Development Environment (IDE), and build the application logic. Everybody is working on the same code. Every iteration - after getting feedback from customers - gets done faster. Improving the time to market but also customer-centricity.

​然后,可以在Qt Design Studio中立即修改功能性UI代码,始终使用可视化编辑器和UI外观的实时预览。打破筒仓并不止于此。后端开发人员可以将从Qt Design Studio创建的代码直接导入Qt Creator,即集成开发环境(IDE),并构建应用程序逻辑。每个人都在使用相同的代码。每次迭代——从客户那里得到反馈之后——都会更快地完成。提高了上市时间,但也以客户为中心。

Illustration: Qt Product Creation Workflow

插图:Qt产品创建工作流

Product creation productivity is not only positively impacted by making UI Designers and UI Developers as well as UI Developers and Back-End Developers work closer together. Readily available software components for the UI and the application logic accelerate the creation of the first prototype. Ready reference build images for different operating systems speed up the build process. Automating functional UI testing removes delays in every development iteration. But describing all these benefits in detail goes beyond the scope of this blog post.

让UI设计师和UI开发人员以及UI开发人员和后端开发人员更紧密地合作,不仅会对产品创建生产力产生积极影响。用户界面和应用程序逻辑的现成软件组件加速了第一个原型的创建。不同操作系统的现成参考构建映像加快了构建过程。自动化功能UI测试消除了每次开发迭代中的延迟。但详细描述所有这些好处超出了本文的范围。


Using an integrated toolchain speeds up your product creation. But don’t take my word for it. Working for Qt, I am biased. Rather consider the words of our customers. For example, Vlochea - using Qt to build a real-time voice-to-MIDI controller application – say “If I was to create a complex UI in C++ and OpenGL it would take me a week, I can produce the same thing in a few hours without much or any performance loss.” You can check out more about Vlochea’s lightning-fast application here.

​使用集成的工具链可以加快产品的创建。但别相信我的话。为Qt工作,我有偏见。宁可考虑客户的话。例如,VoChea-使用QT来构建MIDI控制器应用程序的实时语音——比如“如果我要在C++和OpenGL中创建复杂的UI,我需要一个星期的时间,我可以在几个小时内产生同样的事情而不会有太多或任何性能损失。”你可以在这里查看更多关于Vlochea闪电般的应用程序。

If you are interested to hear more about Qt and how it can accelerate your application development, then please do contact us.

​如果您有兴趣了解更多关于Qt以及它如何加速应用程序开发的信息,请联系我们。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++程序使用QML QML API是分为三个主类——QDeclarativeEngine, QdeclarativeComponent 与 QDeclarativeContext。QDeclarativeEngine 提供QML运行的环境,QdeclarativeComponent 封装了QML Documents 与QDeclarativeContext允许程序导出数据到QML组件实例。 QML还包含了API的一个方便,通过QDeclarativeView 应用程序只需要简单嵌入QML组件到一个新的QGraphicsView就可以了。这有许多细节将在下面讨论。QDeclarativeView 主要是用于快速成型的应用程序里。 如果你是重新改进使用QML的Qt应用程序,请参阅 整合QML到现有的Qt UI代码。 基本用法 每个应用程序至少需求一个QDeclarativeEngine。QDeclarativeEngine允许配置全局设置应用到所有的QML组件实例中,例如QNetworkAccessManager是用于网络通信以及永久储存的路径。如果应用程序需求在QML组件实例间需求不同的设置只需要多个QDeclarativeEngine。 使用QDeclarativeComponent类载入QML Documents。每个QDeclarativeComponent实例呈现单一QML文档。QDeclarativeComponent可以传递一个文档的地址或文档的原始文本内容。该文档的URL可以是本地文件系统的地址或通过QNetworkAccessManager支持的网络地址。 QML组件实例通过调用QDeclarativeComponent::create()模式来创建。在这里载入一个QML文档的示例并且从它这里创建一个对象。 QDeclarativeEngine *engine = new QDeclarativeEngine(parent); QDeclarativeComponent component(engine, QUrl::fromLocalFile(“main.qml”)); QObject *myObject = component.create(); 导出数据 QML组件是以QDeclarativeContext实例化的。context允许应用程序导出数据到该QML组件实例中。单个QDeclarativeContext 可用于一应用程序的所有实例对象或针对每个实例使用QDeclarativeContext 可以创建更为精确的控制导出数据。如果不传递一个context给QDeclarativeComponent::create()模式;那么将使用QDeclarativeEngine的root context。数据导出通过该root context对所有对象实例是有效的。 简单数据 为了导出数据到一个QML组件实例,应用程序设置Context属性;然后由QML属性绑定的名称与JavaScrip访问。下面的例子显示通过QGraphicsView如何导出一个背景颜色到QML文件中: //main.cpp #include <QApplication> #include <QDeclarativeView> #include <QDeclarativeContext> int main(int argc, char *argv[]) { QApplication app(argc, argv); QDeclarativeView view; QDeclarativeContext *context = view.rootContext(); context->setContextProperty(“backgroundColor”, QColor(Qt::yellow)); view.setSource(QUrl::fromLocalFile(“main.qml”)); view.show(); return app.exec(); } //main.qml import Qt 4.7 Rectangle { width: 300 height: 300 color: backgroundColor Text { anchors.centerIn: parent text: “Hello Yellow World!” } } 或者,如果你需要main.cpp不需要在QDeclarativeView显示创建的组件,你就需要使用QDeclarativeEngine::rootContext()替代创建QDeclarativeContext实例。 QDeclarativeEngine engine; QDeclarativeContext *windowContext = new QDeclarativeContext(engine.rootContext()); windowContext->setContextProperty(“backgroundColor”, QColor(Qt::yellow)); QDeclarativeComponent component(&engine, “main.qml”); QObject *window = component.create(windowContext); Context属性的操作像QML绑定的标准属性那样——在这个例子中的backgroundColor Context属性改变为红色;那么该组件对象实例将自动更新。注意:删除任意QDeclarativeContext的构造是创建者的事情。当window组件实例撤消时不再需要windowContext时,windowContext必须被消毁。最简单的方法是确保它设置window作为windowContext的父级。 QDeclarativeContexts 是树形结构——除了root context每个QDeclarativeContexts都有一个父级。子级QDeclarativeContexts有效的继承它们父级的context属性。这使应用程序分隔不同数据导出到不同的QML对象实例有更多自由性。如果QDeclarativeContext设置一context属性,同样它父级也被影响,新的context属性是父级的影子。如下例子中,background context属性是Context 1,也是root context里background context属性的影子。 结构化数据 context属性同样可用于输出结构化与写数据到QML对象。除了QVariant支持所有已经存在的类型外,QObject 派生类型可以分配给context属性。 QObject context属性允许数据结构化输出并允许QML来设置值。 下例创建CustomPalette对象并设置它作为palette context属性。 class CustomPalette : public QObject { Q_OBJECT Q_PROPERTY(QColor background READ background WRITE setBackground NOTIFY backgroundChanged) Q_PROPERTY(QColor text READ text WRITE setText NOTIFY textChanged) public: CustomPalette() : m_background(Qt::white), m_text(Qt::black) {} QColor background() const { return m_background; } void setBackground(const QColor &c) { if (c != m_background) { m_background = c; emit backgroundChanged(); } } QColor text() const { return m_text; } void setText(const QColor &c) { if (c != m_text) { m_text = c; emit textChanged(); } } signals: void textChanged(); void backgroundChanged(); private: QColor m_background; QColor m_text; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QDeclarativeView view; view.rootContext()->setContextProperty(“palette”, new CustomPalette); view.setSource(QUrl::fromLocalFile(“main.qml”)); view.show(); return app.exec(); } QML引用palette对象以及它的属性,为了设置背景与文本的颜色,这里是当单击窗口时,面板的文本颜色将改变成蓝色。 import Qt 4.7 Rectangle { width: 240 height: 320 color: palette.background Text { anchors.centerIn: parent color: palette.text text: “Click me to change color!” } MouseArea { anchors.fill: parent onClicked: { palette.text = “blue”; } } } 可以检测一个C++属性值——这种情况下的CustomPalette的文本属性改变,该属性必须有相应的NOTIFY信息。NOTIFY信号是属性值改变时将指定一个信号发射。 实现者应该注意的是,只有值改变时才发射信号,以防止发生死循环。访问一个绑定的属性,没有NOTIFY信号的话,将导致QML在运行时发出警告信息。 动态结构化数据 如果应用程序对结构化过于动态编译QObject类型;那么对动态结构化数据可在运行使用QDeclarativePropertyMap 类构造。 从QML调用 C++ 通过public slots输出模式或Q_INVOKABLE标记模式使它可以调用QObject派生出的类型。 C++模式同样可以有参数并且可以返回值。QML支持如下类型: •bool •unsigned int, int •float, double, qreal •QString •QUrl •QColor •QDate,QTime,QDateTime •QPoint,QPointF •QSize,QSizeF •QRect,QRectF •QVariant 下面例子演示了,当MouseArea单击时控制“Stopwatch”对象的开关。 //main.cpp class Stopwatch : public QObject { Q_OBJECT public: Stopwatch(); Q_INVOKABLE bool isRunning() const; public slots: void start(); void stop(); private: bool m_running; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QDeclarativeView view; view.rootContext()->setContextProperty(“stopwatch”, new Stopwatch); view.setSource(QUrl::fromLocalFile(“main.qml”)); view.show(); return app.exec(); } //main.qml import Qt 4.7 Rectangle { width: 300 height: 300 MouseArea { anchors.fill: parent onClicked: { if (stopwatch.isRunning()) stopwatch.stop() else stopwatch.start(); } } } 值得注意的是,在这个特殊的例子里有更好的方法来达到同样的效果,在main.qml有”running”属性,这将会是一个非常优秀的QML代码: // main.qml import Qt 4.7 Rectangle { MouseArea { anchors.fill: parent onClicked: stopwatch.running = !stopwatch.running } } 当然,它同样可以调用 functions declared in QML from C++。 网络组件 如果URL传递给QDeclarativeComponent是一网络资源或者QML文档引用一网络资源,QDeclarativeComponent要先获取网络数据;然后才可以创建对象。在这种情况下QDeclarativeComponent将有Loading status。直到组件调用QDeclarativeComponent::create()之前,应用程序将一直等待。 下面的例子显示如何从一个网络资源载入QML文件。在创建QDeclarativeComponent之后,它测试组件是否加载。如果是,它连接QDeclarativeComponent::statusChanged()信号,否则直接调用continueLoading()。这个测试是必要的,甚至URL都可以是远程的,只是在这种情况下要防组件是被缓存的。 MyApplication::MyApplication() { // … component = new QDeclarativeComponent(engine, QUrl(“http://www.example.com/main.qml”)); if (component->isLoading()) QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueLoading())); else continueLoading(); } void MyApplication::continueLoading() { if (component->isError()) { qWarning() << component->errors(); } else { QObject *myObject = component->create(); } } Qt资源 QML的内容可以使用qrc:URL方案从Qt 资源系统载入。例如: [project/example.qrc] <!DOCTYPE RCC> <RCC version=”1.0″> <qresource prefix=”/”> <file>main.qml</file> <file>images/background.png</file> </qresource> </RCC> [project/project.pro] QT += declarative SOURCES += main.cpp RESOURCES += example.qrc [project/main.cpp] int main(int argc, char *argv[]) { QApplication app(argc, argv); QDeclarativeView view; view.setSource(QUrl(“qrc:/main.qml”)); view.show(); return app.exec(); } [project/main.qml] import Qt 4.7 Image { source: “images/background.png” } 请注意,资源系统是不能从QML直接访问的。如果主QML文件被加载作为资源,所有的文件指定在QML中做为相对路径从资源系统载入。在QML层使用资源系统是完全透明的。这也意味着,如果主QML文件没有被加载作为资源,那么从QML不能访问资源系统。 1.这里主要是介绍,如何在c++中调用QML中的函数和设置QML中的属性的问题 2.具体代码 // UICtest.qml import Qt 4.7 Rectangle { id: mainWidget; width: 640 height: 480 function callbyc(v) { mainWidget.color = v; return "finish"; } Rectangle{ id: secondRect; x: 100; y: 20; width: 400; height: 300; Rectangle{ x: 10; y: 20; width: 30; height: 40; color: "#FF035721" Text { objectName: "NeedFindObj"; anchors.fill: parent; text: ""; } } } } // main.cpp #include <QtGui/QApplication> #include <QtDeclarative/QDeclarativeView> #include <QtDeclarative/QDeclarativeEngine> #include <QtDeclarative/QDeclarativeComponent> #include <QtDeclarative/QDeclarativeContext> #include <QtDeclarative/QDeclarativeItem> #include <QMetaObject> int main(int argc, char *argv[]) { QApplication a(argc, argv); QDeclarativeView qmlView; qmlView.setSource(QUrl::fromLocalFile("../UICtest/UICtest.qml")); qmlView.show(); // 获取根节点,就是 QML中 id是mainWidget的节点 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(qmlView.rootObject()); item->setProperty("color", QVariant("blue")); // 查找到我们需要的节点根均objectname NeedFindObj 来获得,并设置他的文本属性 QDeclarativeItem *item1 = item->findChild<QDeclarativeItem *>("NeedFindObj"); if (item1) { item1->setProperty("text", QVariant("OK")); } // 调用QML中的函数, 分别是 函数所在的对象, 函数名,返回值, 参数 QVariant returnVar; QVariant arg1 = "blue"; QMetaObject::invokeMethod(item, "callbyc", Q_RETURN_ARG(QVariant, returnVar),Q_ARG(QVariant, arg1)); qDebug(" %s",returnVar.toString().toLocal8Bit().data()); return a.exec(); } 说明: 这里的根节点是id为mainWidget的矩形元素,那么在C++中获取根节点后就可以,直接的设置他的属性了。其他属性也可以同样,调用指定节点内的函数是通过QMetaObject中的invokeMethod 来进行调用的。 最后所有关于QML和c++交互部分就基本写完,如果想要更多的东西,或者一些其他方法,强烈看看 http://doc.qt.nokia.com/4.7-snapshot/qtbinding.html,或者帮助文档,(究竟是不是我的文档里面没有还是怎么的)
### 回答1: Qt是一个跨平台的应用程序开发框架,能够快速开发各种类型的应用程序Qt提供了丰富的工具和库,使开发者能够轻松地设计、编写和调试高质量的图形用户界面。 Qt使用C++编程语言,具有良好的可扩展性和可移植性。开发者可以使用Qt的类和函数来创建自定义的对象,并根据自己的需求进行扩展和修改。Qt还提供了丰富的API和示例代码,帮助开发者快速理解和掌握开发流程。 Qt的主要特点之一是其跨平台能力。开发者可以使用Qt编写一次代码,然后在不同的操作系统和设备上部署并运行。无论是在Windows、Mac、Linux还是移动平台上,开发者都可以使用Qt进行开发,并且代码的可移植性非常好。 除了跨平台能力,Qt还提供了许多特性和模块,帮助开发者快速开发出功能强大的应用程序。例如,Qt提供了图形渲染引擎、网络功能、数据库访问、XML处理等模块,使开发者能够轻松地集成这些功能到他们的应用程序中。 另外,Qt还支持多种开发方式。开发者可以选择使用Qt的集成开发环境(Qt Creator)来进行开发,也可以使用其他的IDE,如Visual Studio等。Qt还支持各种主流的编译器,包括GCC、Clang、MSVC等。 总而言之,Qt是一个通用的快速开发框架,具有跨平台能力、丰富的功能模块和易用的开发工具。使用Qt,开发者能够更加高效地开发出高质量、可扩展的应用程序。 ### 回答2: Qt是一个跨平台的应用程序开发框架,被广泛用于开发图形界面(GUI)应用程序。它提供了丰富的功能和工具,使开发者能够快速而灵活地开发各种应用程序。 首先,Qt具有跨平台的特性,这意味着开发者可以用一套代码在不同的操作系统上运行应用程序,无需重新编写代码。Qt支持多种操作系统,包括Windows、Linux、MacOS等。 其次,Qt提供了大量的易于使用的类和函数,简化了开发过程。开发者可以利用Qt提供的预定义控件、图形绘制函数和布局管理器来快速构建用户界面,并使用信号与槽机制进行事件处理。这些功能可以大大提高开发效率。 另外,Qt框架还包括了许多用于处理非GUI相关任务的模块,如网络通信、数据库访问、多线程处理等。这些功能使开发者能够更轻松地处理各种常见任务,而无需编写大量的底层代码。 此外,Qt提供了用于国际化和本地化的工具,使应用程序能够支持不同语言和地区的用户。开发者可以轻松地将应用程序翻译成多种语言,从而扩展用户群体。 总的来说,Qt是一个功能强大而灵活的应用程序开发框架,提供了丰富的功能和工具,使开发者能够快速构建跨平台的GUI应用程序。它的易用性和高效性使其成为许多开发者的首选框架。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值