一、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 Labs
Window {
width: 640
height: 480
visible: true
title: qsTr("GongJianBo")
Button {
text: "open"
onClicked: {
dialog2.open()
}
}
QD.FileDialog {
id: dialog1
selectFolder: true
onAccepted: {
console.log(dialog1.folder)
}
}
Labs.FolderDialog {
id: dialog2
onAccepted: {
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.running
opacity: control.running ? 1 : 0
Behavior 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: pop
contentItem: BusyIndicator {
id: busy
width: 80
height: 80
running: 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 中,经测试默认可以正确加载修改了后缀的图片。