一、Qt Widgets 问题交流
二、Qt Quick 问题交流
1、在 C++ 中关联 QQuickWindow 的 closing 信号提示 "使用了未定义类型QQuickCloseEvent"
因为 closing 信号中的参数类型是 private 模块中定义的,但是通过第二句提示我们知道找到了完整定义才能使用 Q_DECLARE_METATYPE(T*) ,而 Qt 提供了不透明指针宏 Q_DECLARE_OPAQUE_POINTER ,使得应用 Q_DECLARE_METATYPE(T*) 时不必找到完整定义。
加上此宏后即可以编译通过,只是不能接收这个参数:
Q_DECLARE_OPAQUE_POINTER(QQuickCloseEvent*)
int main(int argc, char *argv[])
{QGuiApplication app(argc, argv);QQmlApplicationEngine engine;const QUrl url(QStringLiteral("qrc:/main.qml"));QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [&myobj, url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);QQuickWindow *win = qobject_cast<QQuickWindow*>(obj);if (win) {QObject::connect(win, &QQuickWindow::closing, [](){});}}, Qt::QueuedConnection);engine.load(url);return app.exec();
}
另一种能够通过编译的方式是使用 SIGNAL/SLOT 宏来关联信号槽:
QObject::connect(win, SIGNAL(closing(QQuickCloseEvent*)),&myobj, SLOT(onClose()));
2、QML 的文件夹对话框没有进入该目录只是单击选中那么 folder 属性获取不到这个文件夹
如图,单机选中 QtOnline 文件夹,并点击 【选择文件夹】按钮
此时打印 FolderDialog 的 folder 属性,不会出现 QtOnline ,除非双击进入这个目录
QtWidget 的 QFileDialog 就能正确的获取这个路径。
测试代码:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Dialogs 1.3 as QD
import Qt.labs.platform 1.1 as LabsWindow {width: 640height: 480visible: truetitle: qsTr("GongJianBo")Button {text: "open"onClicked: {dialog2.open()}}QD.FileDialog {id: dialog1selectFolder: trueonAccepted: {console.log(dialog1.folder)}}Labs.FolderDialog {id: dialog2onAccepted: {console.log(dialog2.folder)}}
}
3、BusyIndicator 如果 running 绑定 visible,那么隐藏后第二次 visible 为 true 时不会显示出来
图一是第一次 visible,图二是第二次 visible。
BusyIndicator 内部使用了一个透明度动画,runing 的时候透明度为 1,停止时为 0。而在事件处理中,透明度为 0 时又会设置 visible 为 false。
T.BusyIndicator {contentItem: BusyIndicatorImpl {running: control.runningopacity: control.running ? 1 : 0Behavior on opacity { OpacityAnimator { duration: 250 } }}
}
void QQuickDefaultBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
{QQuickItem::itemChange(change, data);switch (change) {case ItemOpacityHasChanged:if (qFuzzyIsNull(data.realValue))setVisible(false);break;case ItemVisibleHasChanged:update();break;default:break;}
}
可是即使我们调整透明度动画大于 0 ,仍然不能显示,那是因为源码用的 OpacityAnimator,只在开始和结束触发值改变的信号,而且就算指定了起止 from 和 to,最终也是在 0 和 1 变化。
不过,我们根本不需要设置 runing 为 false,因为源码中逻辑可能和我们想的不一样,我们只需要设置 visible 即可。
void QQuickDefaultBusyIndicator::setRunning(bool running)
{if (running)setVisible(true);
}
测试代码:
Button {text: "pop"onClicked: pop.open()}Popup {id: popcontentItem: BusyIndicator {id: busywidth: 80height: 80running: visible}}
三、其他
1、QImage 的数据默认至少 4 字节对齐
QImage 文档:https://doc.qt.io/qt-5.15/qimage.html
通过 bits() 返回的地址操作内部连续数据时,需要注意行对齐问题,可以通过 bytesPerLine() 获取每行字节数,也可以通过 scanLine(int i) 接口来逐行遍历。
2、QImage/QImageReader 加载修改了后缀名的图片
在旧版本中如果图片改了后缀名,QImage 可能无法正常加载,因为默认以后缀名来确认格式。可以通过 QImageReader 来读取,设置 decideFormatFromContent 为 true 后不以后缀判断格式:
QImageReader reader(filepath);//setDecideFormatFromContent之前调用format会导致设置无效//qDebug()<<reader.format();reader.setDecideFormatFromContent(true);qDebug()<<reader.format();QImage img = reader.read();
在 Qt5.15 中,经测试默认可以正确加载修改了后缀的图片。