qt-qml-attachments
10
总安装量
3
周安装量
#30698
全站排名
安装命令
npx skills add https://github.com/bohdan-shulha/skills --skill qt-qml-attachments
Agent 安装分布
codex
3
claude-code
2
amp
1
opencode
1
kimi-cli
1
github-copilot
1
Skill 文档
Qt Qml Attachments
Overview
Fix and tune QML chat attachment layouts so chips/images wrap in rows, align to the correct side, preserve ordering, and keep message bubbles from stretching full width.
Quick Diagnosis
- If attachments stack vertically, the Flow likely has no usable width. Avoid binding
Flow.widthto its ownimplicitWidth. - If the row aligns left when it should align right, check
layoutDirection, anchors, and model order. - If bubbles appear full-width, clamp
Layout.preferredWidthand Flow width to a max ratio or fixed pixel cap.
Flow Width & Wrap
- Give
Flowan explicit width based on available space (e.g.,chatArea.width - margins). - Use
Math.max(0, ...)to avoid negative widths during resize. - For the container height, prefer
implicitHeightoverheightwhen itâs driven by a Flow.
Example:
Item {
implicitHeight: attachmentsFlow.implicitHeight
Flow {
id: attachmentsFlow
width: Math.max(0, Math.min(chatArea.width - 120, chatArea.width * 0.65))
spacing: 8
}
}
Right-Aligning Attachments
- Set
anchors.right: parent.righton the Flow container. - Use
layoutDirection: Qt.RightToLeftfor a right-aligned wrap. - Preserve order: if you want newest on the right, keep the model order and use
RightToLeft. - Preserve chronological left-to-right: reverse the model when using
RightToLeft.
Order rules:
- Model is oldest â newest:
RightToLeftshows newest on the right. - Model is newest â oldest: reverse it or switch to
LeftToRight.
Bubble Width Caps
- Clamp
Layout.preferredWidthso bubbles donât stretch full width, even for long text or many attachments. - Use a ratio (e.g.,
0.6â0.7) or a fixed max pixel value.
Example:
Rectangle {
Layout.preferredWidth: Math.min(msgText.implicitWidth + 24, chatArea.width * 0.65)
Layout.preferredHeight: msgText.height + 16
}
Clipboard Image Attachments (Qt)
- Always read clipboard image data on the GUI thread (
qApp->thread()), otherwiseQClipboardmay return empty. - Prefer
QClipboard::image()but add fallbacks:application/x-qt-image, thenmime->imageData()toQImageorQPixmap. - Normalize image format and colorspace before saving to PNG to avoid libpng/ICC crashes.
- Save to a temp attachment folder and return a file path for QML to attach.
Example:
if (QThread::currentThread() != qApp->thread())
return "";
QImage image = clipboard->image();
if (image.isNull() && mime->hasFormat("application/x-qt-image")) {
QByteArray raw = mime->data("application/x-qt-image");
QDataStream stream(&raw, QIODevice::ReadOnly);
stream >> image;
if (stream.status() != QDataStream::Ok)
image = QImage();
}
if (image.isNull()) {
QVariant data = mime->imageData();
if (data.canConvert<QImage>())
image = data.value<QImage>();
else if (data.canConvert<QPixmap>())
image = data.value<QPixmap>().toImage();
}
if (image.isNull())
return "";
if (image.format() != QImage::Format_RGBA8888)
image = image.convertToFormat(QImage::Format_RGBA8888);
image.setColorSpace(QColorSpace::SRgb);
image = image.copy();
Common Pitfalls
Flow.width: implicitWidthoften collapses to a single-column layout.- Using
heightinstead ofimplicitHeighton containers causes clipping or over-expansion. - Right alignment without
layoutDirectionkeeps the wrap left-biased. - Long filenames: cap chip width with
Text.elideand a fixed max width.