QQuickPaintedItem对齐不正确

时间:2018-07-23 19:22:59

标签: qt qml

我已经在C ++中创建了一个自定义QQuickPaintedItem,但是在使用它时,ColumnLayout中的QML端会忽略Q.AlignHCenter属性。对齐它的唯一方法是将我的自定义项放入Item元素中。例如:

此操作无效,该项目比实际居中位置更靠右放置:

BalanceItem {
    Layout.alignment: Qt.AlignHCenter
    id: acct_balance_item
}

这确实有效,该项目确实居中:

Item {
    Layout.preferredWidth: acct_balance_item.width
    Layout.preferredHeight: acct_balance_item.height
    Layout.alignment: Qt.AlignHCenter
    BalanceItem {
        id: acct_balance_item
    }
}

我的绘画方法如下:

void BalanceItem::paint(QPainter* painter) {
    int w;
    int accum_w=0;
    QColor hi_color;

    hi_color.setRgb((unsigned int) 0x00ffffff);
    QColor dot_color((QRgb) 0x00FFFFFF);
    QColor lo_color((QRgb) 0x00888888);

    QPen pen(hi_color, 2);
    painter->setPen(pen);
    QFont font=painter->font();
    font.setPointSize ( 12 );
    font.setWeight(QFont::Bold);
    QFontMetrics fm(font);
    w=fm.width(this->hi_fmt);
    painter->setFont(font);
    painter->drawText(QPoint(0,20),this->hi_fmt);
    accum_w+=w;

    w=fm.width(".");
    pen.setColor(dot_color);
    painter->setPen(pen);
    painter->drawText(QPoint(accum_w,20),".");
    accum_w+=w;


    font.setWeight(QFont::Normal);
    fm=QFontMetrics(font);
    w=fm.width(this->lo_fmt);
    painter->setFont(font);
    pen.setColor(lo_color);
    painter->setPen(pen);
    painter->drawText(QPoint(accum_w,20),this->lo_fmt);
    accum_w+=w;

    QString symstr(" "+this->symbol);
    w=fm.width(symstr);
    painter->drawText(QPoint(accum_w,20),symstr);
    accum_w+=w;

    this->fld_width=accum_w;
    this->setWidth(this->fld_width);
}

我怀疑是它使用了Constructor设置的项目的初始宽度,但是这个宽度只是初始设置,最后在paint()方法期间重新计算了实际宽度。

那么,如何使我的自定义QQuickPaintedItem在ColumnLayout中正确对齐?

1 个答案:

答案 0 :(得分:2)

您的第一个代码不起作用,因为public getConversations(user_id: string): Observable<Conversation[]> { return this.firebase .collection<Participant>(this.PARTICIPANTS_COLLECTION, ref => ref.where('user_id', '==', user_id) ) .valueChanges() .map((participants: Participant[]) => { const conversation_ids: string[] = []; participants.forEach((p: Participant) => conversation_ids.push(p.conversation_id)); return conversation_ids; }) .mergeMap((ids: string[]) => { let conversations: Observable<Conversation[]> = new Observable<Conversation[]>(); for(let id of ids) { conversations.merge( this.firebase.collection<Conversation>(this.CONVERSATIONS_COLLECTION, ref => ref.where('id', '==', id) ).valueChanges() // I want to merge these ); } return conversations; // I want to return this }); } 修改了ColumnLayout的宽度和高度。这就是Qt Quick中的布局,他们管理子级的大小和位置。为了做到这一点,他们需要知道孩子的大小。

他们不能用BalanceItemwidth来做,因为他们稍后会对其进行修改。 在第二个示例中,如果您完成height,它也会失败。 width: acct_balance_item.width的宽度和高度最终将为0。

要告诉布局一个项目想要的尺寸,它们是2个解决方案。您将其与Item附加属性Layout一起使用,将您的preferred|minimum|maximum/Width|Height / implicitWidth属性与implicitHeight / Item一起使用。

隐含大小是指未设置任何显式大小(使用QQuickItemwidth)时项目所占的大小。有些项目的隐式大小设置为0(例如普通的heightItem),但是有些项可能会定义其隐式大小,以告知父级/用户默认有意义的大小。例如,Rectangle定义其隐式大小,以便使其适合其所有文本。但是您可以对其施加一定的宽度,如果显式Text小于其Text,则text可能会包裹或退出其width

因此,您的问题是您的implicitWidthBalanceItem的宽度和高度为0,但是您没有注意到,因为默认情况下未启用裁剪,并且您在项目的尺寸之外进行了绘制在您的ColumnLayout方法中。

定义项目组件时,不应设置其paintwidth属性。如果对您的商品有意义,则可以定义heightimplicitWidth

如果您能以某种方式压缩/扩展组件,也可以只在项目的区域绘画来处理显式尺寸。但是您不必/不希望(如果您不启用省略或环绕,implicitHeight则不会这样做)。

为减轻将来出现的商品几何问题,您可以尝试调试它,方法是将一个带有颜色的子项TextRectangle(也许有些不透明),以可视化您商品的尺寸。或使用出色的Qt调试软件GammaRay