一、Qt Widgets 问题交流
1.
二、Qt Quick 问题交流
1.QML单例动态创建的对象,访问外部id提示undefined
先定义一个窗口组件,打印外部的id:
// MyWindow.qml
import QtQuick 2.15
import QtQuick.Window 2.15Window {id: controlwidth: 400height: 300visible: falseMouseArea {anchors.fill: parentonClicked: {// transientParent设置parent后可以正常访问console.log(control.transientParent)// 单例创建的不能访问外部的idconsole.log(root)}}
}
单例动态创建MyWindow :
// MySingleton.qml
pragma Singleton
import QtQuick 2.15Item {function createWindow(parent = null){let comp = Qt.createComponent("MyWindow.qml", Component.PreferSynchronous, parent)let win = comp.createObject(parent)return win}
}
测试可以看到在非单例动态创建的对象可以访问外部id,动态创建的不行:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15Window {id: rootwidth: 640height: 480visible: truetitle: qsTr("GongJianBo")Row {anchors.fill: parentspacing: 10Button {text: "Singleton"onClicked: {let win = MySingleton.createWindow(root)win.show()}}Button {text: "Normal"onClicked: {let comp = Qt.createComponent("MyWindow.qml")let win = comp.createObject(root)win.show()}}}
}
将Window类型替换成Rectangle也是一样的结果。
三、其他
1.Qt5 QImage SmoothTransformation 缩放后格式改变
Qt Bug Tracker:https://bugreports.qt.io/browse/QTBUG-49719
测试代码:
QImage img = QImage(100, 100, QImage::Format_RGB888);img.fill(Qt::red);qDebug() << img.format();// 输出:QImage::Format_RGB888img = img.scaled(50, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation);qDebug() << img.format();// Qt5输出:QImage::Format_RGB32// Qt6输出:QImage::Format_RGB888
如RGB888变成了RGB32,ARGB32变成了ARGB32_Premultiplied等
从源码一探究竟,scaled函数中调用了transformed函数:
QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
{if (!d) {qWarning("QImage::scaled: Image is a null image");return QImage();}if (s.isEmpty())return QImage();QSize newSize = size();newSize.scale(s, aspectMode);newSize.rwidth() = qMax(newSize.width(), 1);newSize.rheight() = qMax(newSize.height(), 1);if (newSize == size())return *this;Q_TRACE_SCOPE(QImage_scaled, s, aspectMode, mode);QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), (qreal)newSize.height() / height());QImage img = transformed(wm, mode);return img;
}
transformed函数中调用了smoothScaled函数:
QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode ) const
{... ...// Make use of the optimized algorithm when we're scalingif (scale_xform && mode == Qt::SmoothTransformation) {if (mat.m11() < 0.0F && mat.m22() < 0.0F) { // horizontal/vertical flipreturn smoothScaled(wd, hd).mirrored(true, true);} else if (mat.m11() < 0.0F) { // horizontal flipreturn smoothScaled(wd, hd).mirrored(true, false);} else if (mat.m22() < 0.0F) { // vertical flipreturn smoothScaled(wd, hd).mirrored(false, true);} else { // no flippingreturn smoothScaled(wd, hd);}}... ...
}
smoothScaled中就需要转换成固定的几种格式来缩放了:
QImage QImage::smoothScaled(int w, int h) const {QImage src = *this;switch (src.format()) {case QImage::Format_RGB32:case QImage::Format_ARGB32_Premultiplied:
#if Q_BYTE_ORDER == Q_LITTLE_ENDIANcase QImage::Format_RGBX8888:
#endifcase QImage::Format_RGBA8888_Premultiplied:
#if QT_CONFIG(raster_64bit)case QImage::Format_RGBX64:case QImage::Format_RGBA64_Premultiplied:break;case QImage::Format_RGBA64:src = src.convertToFormat(QImage::Format_RGBA64_Premultiplied);break;
#endifdefault:if (src.hasAlphaChannel())src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);elsesrc = src.convertToFormat(QImage::Format_RGB32);}src = qSmoothScaleImage(src, w, h);if (!src.isNull())copyMetadata(src.d, d);return src;
}QImage qSmoothScaleImage(const QImage &src, int dw, int dh)
{QImage buffer;if (src.isNull() || dw <= 0 || dh <= 0)return buffer;int w = src.width();int h = src.height();QImageScaleInfo *scaleinfo =qimageCalcScaleInfo(src, w, h, dw, dh, true);if (!scaleinfo)return buffer;buffer = QImage(dw, dh, src.format());if (buffer.isNull()) {qWarning("QImage: out of memory, returning null");qimageFreeScaleInfo(scaleinfo);return QImage();}#if QT_CONFIG(raster_64bit)if (src.depth() > 32)qt_qimageScaleRgba64(scaleinfo, (QRgba64 *)buffer.scanLine(0),dw, dh, dw, src.bytesPerLine() / 8);else
#endifif (src.hasAlphaChannel())qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0),dw, dh, dw, src.bytesPerLine() / 4);elseqt_qimageScaleAARGB(scaleinfo, (unsigned int *)buffer.scanLine(0),dw, dh, dw, src.bytesPerLine() / 4);qimageFreeScaleInfo(scaleinfo);return buffer;
}
查看Qt6的代码,发现调用smoothScaled后又转换回原格式了:
QImage Q_TRACE_INSTRUMENT(qtgui) QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode ) const
{... ...if (scale_xform && mode == Qt::SmoothTransformation) {switch (format()) {case QImage::Format_RGB32:case QImage::Format_ARGB32_Premultiplied:
#if Q_BYTE_ORDER == Q_LITTLE_ENDIANcase QImage::Format_RGBX8888:
#endifcase QImage::Format_RGBA8888_Premultiplied:
#if QT_CONFIG(raster_64bit)case QImage::Format_RGBX64:case QImage::Format_RGBA64_Premultiplied:
#endifcase QImage::Format_CMYK8888:// Use smoothScaled for scaling when we can do so without conversion.if (mat.m11() > 0.0F && mat.m22() > 0.0F)return smoothScaled(wd, hd);break;default:break;}// Otherwise only use it when the scaling factor demands it, or the image is large enough to scale multi-threadedif (nonpaintable_scale_xform
#if QT_CONFIG(thread) && !defined(Q_OS_WASM)|| (ws * hs) >= (1<<20)
#endif) {QImage scaledImage;if (mat.m11() < 0.0F && mat.m22() < 0.0F) { // horizontal/vertical flipscaledImage = smoothScaled(wd, hd).mirrored(true, true);} else if (mat.m11() < 0.0F) { // horizontal flipscaledImage = smoothScaled(wd, hd).mirrored(true, false);} else if (mat.m22() < 0.0F) { // vertical flipscaledImage = smoothScaled(wd, hd).mirrored(false, true);} else { // no flippingscaledImage = smoothScaled(wd, hd);}switch (format()) {case QImage::Format_Mono:case QImage::Format_MonoLSB:case QImage::Format_Indexed8:return scaledImage;default:return scaledImage.convertToFormat(format());}}}... ...
}
2.Qt Creator 15/16 等新版本工具菜单没有翻译相关选项
Qt Creator 15/16 等新版本的工具菜单中,外部选项里没有翻译相关选项了,但是可以手动添加回去,参考:https://blog.csdn.net/weixin_53735713/article/details/144442073
在外部配置选项里选择添加工具:
// 新增工具-更新翻译lupdate
%{CurrentDocument:Project:QT_INSTALL_BINS}\lupdate
%{CurrentDocument:Project:FilePath}
%{CurrentDocument:Project:Path}// 新增工具-发布翻译lrelease
%{CurrentDocument:Project:QT_INSTALL_BINS}\lrelease
%{CurrentDocument:Project:FilePath}
%{CurrentDocument:Project:Path}
三行分别对应:执行档,参数,工作目录,在测试时参数前面多加了个空格导致执行参数有问题。