我正在将一些Qt(C++和QML)代码从Qt4.8升级到Qt5.1.
Qt4.8代码是一个简单的C++"QML查看器"应用程序子类化a QDeclarativeView和一堆QML.
QQuickView除了一件事之外,很容易将其更改为使用Qt5/QtQuick2 :
Qt4.8应用程序有一个打印到PDF的方法:
void MyQMLViewer::printToPDF(const QString& filename) const {
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setPageSize(QPrinter::A3);
printer.setOutputFileName(filename);
printer.setOrientation(QPrinter::Landscape);
QPainter painter(&printer);
render(&painter);
}
Run Code Online (Sandbox Code Playgroud)
Qt5.1需要进行一些"环境"更改才能获得QPrinter(即添加QT += printsupport到项目.pro文件中#include <QtPrintSupport>),但似乎有一个更基本的问题,QQuickView它不提供任何明显与QGraphicsView/ 兼容的东西.QPainter/ QPaintDeviceworld of QPrinter(具体来说,QQuickView没有render方法,所有绘图/绘画/渲染相关的方法看起来与OpenGL非常相关).
有关如何从中获得高质量PDF输出的任何建议QQuickView?
(请注意,我not只是希望截图的视图;与QDeclarativeView上面的代码生成的PDF文件与很多更好的分辨率甚至超过了应用程序全屏我最大的显示器上).
我看到"将QML应用程序移植到Qt 5"指南中的"QDeclarativeItem和QDeclarativeView"部分确实提到了QGraphicsView特定功能的丢失,但没有提供任何解决方案(尽管它确实提到了带有自定义项目的工作场所QPainter-基础渲染被买入新政权).
更新一些额外的背景信息:可以在此处找到使用上述代码从QDeclarativeView打印的PDF示例.有一个体面的大小监视器上相同的观点的PNG 这里.(这实际上是一系列幻灯片中的最后一张幻灯片;它实际上是以前幻灯片的一个画廊,它将每张幻灯片反弹到屏幕上;如果我有时间,我会考虑画廊的可行性是唯一的改变每个分散的幻灯片进入Prezi风格的演示视图;怀疑QDeclarative虽然不够真实,这是想要进入QtQuick2 + Qt5.2的新场景图形的一个原因).无论如何,如果你将PDF缩放到100%,你会看到文本是...好吧,它比任何一个大小合适的图像文件管理我认为,尽管倾斜的文本基线可能看起来有点不均匀.还有一个问题,不透明度值没有在PDF中表示(因此阴影和"气泡"变得坚固); …
我为Windows 32位安装了Qt 5.0.1(MinGW 4.7,823 MB)
然后我创建了简单的Quick 2应用程序并编译它.应用程序位于其文件夹中,并且应用程序从QtCreator运行.我想在没有QtCreator的情况下运行这个exe文件.为此,我从C:\ Qt\Qt5.0.1\5.0.1\mingw47_32\bin复制文件:
然后我得到错误:
Точкавходавпроцедуру_ZN6icu_4910CharString15getAppendBufferEiiRiR10UErrorCodeненайденавбиблиотекеDLIicuuc49.dll
翻译:
在库DLL icuuc49.dll中找不到过程入口点_ZN6icu_4910CharString15getAppendBufferEiiRiR10UErrorCode
如果我将exe文件复制到文件夹C:\ Qt\Qt5.0.1\5.0.1\mingw47_32\bin(其中都是dll),程序运行,但没有显示.
如果我将exe文件复制到文件夹C:\ Qt\Qt5.0.1\Tools\QtCreator\bin(其中都是dll),程序不会运行.
该怎么办?程序运行的位置和库是什么?
解决了.C:\ Qt\Qt5.0.1\5.0.1\mingw47_32\bin中的最终库列表:
我忘了添加qml文件的文件夹.
我想跟踪一个对象的全局位置(或相对于它的一个祖先)并将其绑定到其他项目的位置.
我正在考虑使用mapFromItem如下:
SomeObject {
x: ancestor.mapFromItem(trackedObject, trackedObject.x, 0).x
y: ancestor.mapFromItem(trackedObject, 0, trackedObject.y).y
}
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是,它mapFromItem被评估一次,并且不会更新,因为其中一个参数得到更新.此外,映射有时返回由我无法在代码中跟踪的偏移量改变的新位置(但这不是手头的问题).
我的第二个想法是通过实现一个函数来计算全局位置,该函数将递归地求和偏移量,停止在提供的祖先(类似的东西calculateOffsetFrom(ancestor)).这仍然只是一个函数,就我而言,它不会被重新评估为祖先位置变化之一(除非,在该函数中,我将绑定调用它的onXChanged每一个信号的信号)沿途的祖先,这似乎是一个肮脏的解决方案).
所以最后我已经添加了我想要跟踪的对象的属性,然后我绑定到它们:
TrackedObject {
property real offsetX: x + parent.x + parent.parent.x + parent.parent.parent.x ...
property real offsetY: y + parent.y + parent.parent.y + parent.parent.parent.y ...
}
SomeObject {
x: trackedObject.globalX
y: trackedObject.globalY
}
Run Code Online (Sandbox Code Playgroud)
但是......好吧......这个根本不会扩展,而且会像它那样难看.
有谁知道如何以更清洁的方式解决这个问题?
编辑:
据我所知,在这种情况下我不能使用锚点.该SomeObject组件是一个自定义组件,从一个点到另一个点绘制贝塞尔曲线(它将连接两个TrackedObjects).为此,我需要坐标之间的差异.如果我是正确的锚,则不提供任何计算它们之间距离的方法.
是否有可能将一个MouseAreapositionChanged事件传播给一个基础事件?
我试图设置mouse.accepted到false为最上面的任何现有的信号处理程序MouseArea,以及设置propagateComposedEvents到true.这些都没有起作用(虽然我对propagateComposedEvents并不工作并不感到惊讶,因为文档说它只传递类似的事件clicked,doubleClicked和pressAndHold).
我有一个包含以下内容的QML文件:
Text {
id: testData
onTaskClicked:{
testData.text = task.name
}
}
Run Code Online (Sandbox Code Playgroud)
捕获是这个任务点击信号.它由另一个小部件(C++)发出,需要中继到QML.
这类似于这个SO问题,除了那里发布的解决方案不起作用(为什么写在下面).
C++代码:
ctxt->setContextProperty(QLatin1Literal("holiday"), m_model);
ctxt->setContextProperty(QLatin1Literal("bgcolor"), color);
view->setResizeMode(QQuickView::SizeRootObjectToView);
auto mainPath = QStandardPaths::locate(QStandardPaths::DataLocation,
QLatin1Literal("taskview.qml"));
view->setSource(QUrl::fromLocalFile(mainPath));
ctxt->setContextProperty(QLatin1Literal("viewer"), m_view);
Run Code Online (Sandbox Code Playgroud)
m_view是一个QListView发出taskClicked(HolidayTask* task)信号的子类(来自.h文件):
Q_SIGNALS:
void taskClicked(HolidayTask* task);
Run Code Online (Sandbox Code Playgroud)
color并m_model在QML注册并在其他地方使用.来自信号的对象已经在QML中注册.view是我的QQuickView.
首先,我尝试了上述问题中提出的解决方案:
auto root = view->rootObject();
auto myElement = root->findChild<QObject*>(QLatin1Literal("testData");
connect(m_view, SIGNAL(taskClicked(HolidayTask* task), myElement,
SLOT(taskClicked(HolidayTask* task);
Run Code Online (Sandbox Code Playgroud)
但是,myElement始终为null(我得到关于不存在的插槽的运行时警告).
如果我尝试将视图(QListView)指针设置为QML视图的上下文属性,它仍然不起作用.
在所有情况下,我也得到:
QML Connections: Cannot assign to non-existent property "onTaskClicked"
Run Code Online (Sandbox Code Playgroud)
我可能在这里做错了什么?
编辑澄清一些细节:HolidayTask是自定义QObject子类,信号 …
在Qt 5.4中,创建新"QtQuick UI文件"时的模板生成两个文件:MyScreen.qml和MyScreen.ui.qml.
该MyScreen.ui.qml文件似乎仅适用于UI,因为Qt Creator建议您只应在设计模式下编辑它.这意味着我应该在那里创建UI对象(标签,按钮等),并以某种方式MyScreen.qml在逻辑所在的文件中引用它们.原则上这听起来不错,但遗憾的是Qt没有提供如何使用这两个文件的任何示例.
以下是这些文件的内容:
MyScreen.qml:
import QtQuick 2.4
MyScreen {
}
Run Code Online (Sandbox Code Playgroud)
MyScreen.ui.qml (我在设计模式中添加了Text标签):
import QtQuick 2.4
Item {
width: 400
height: 400
Text {
id: text1
x: 144
y: 151
width: 103
height: 31
text: qsTr("Text")
font.pixelSize: 12
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试实例化一个MyScreen用于a StackView(见下文),但(不出所料)我没有看到标签.
main.qml :
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
Window {
visible: true
StackView {
id: stack
anchors.fill: parent
initialItem: myscreen
} …Run Code Online (Sandbox Code Playgroud) 这可以按预期使用Row,但不能使用RowLayout.为什么?两者有什么区别?
ApplicationWindow {
title: "Testing"
width: 640
height: 480
//RowLayout {
Row {
anchors.fill: parent
Rectangle {
id: rect1
width: parent.width * 0.3
height: parent.height
color: "blue"
}
Rectangle {
height: parent.height
width: parent.width * 0.7
color: "red"
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试更多地了解QtQuick和QML.我目前的目标是了解如何将数据从C++模型绑定到我的视图.到目前为止,我已经能够在我的QML中设置模型并从模型中获取数据,但我无法弄清楚如何更新我的数据.
如何为我的C++模型设置双向绑定?下面是我到目前为止编写的代码.
message.h
class Message : public QObject
{
Q_OBJECT
Q_PROPERTY(QString author READ getAuthor WRITE setAuthor NOTIFY authorChanged)
Q_PROPERTY(QString message READ getMessage WRITE setMessage NOTIFY messageChanged)
Q_SIGNALS:
void authorChanged(QString author);
void messageChanged(QString message);
public:
Message(QObject *parent = 0);
QString getAuthor();
void setAuthor(QString author);
QString getMessage();
void setMessage(QString message);
private:
QString _author;
QString _message;
};
Run Code Online (Sandbox Code Playgroud)
message.cpp
#include "message.h"
Message::Message(QObject *parent) : QObject(parent)
{
}
QString Message::getAuthor()
{
return _author;
}
void Message::setAuthor(QString author)
{
if(author != _author)
{
_author = author; …Run Code Online (Sandbox Code Playgroud) 我想在QML中使用QAbstractListModel派生模型.将模型绑定到视图已经很有效.
我想要实现的下一件事是能够访问特定项目及其角色,就像使用QML ListModel一样
grid.model.get(index).DisplayRole
Run Code Online (Sandbox Code Playgroud)
但是我不知道如何在我的QAbstractListModel派生模型中实现这个get方法.
任何提示?