【问题标题】:QToolButton with icon + text: How to center both?带有图标+文本的QToolButton:如何使两者居中?
【发布时间】:2015-04-15 11:07:49
【问题描述】:

我在自定义 QGridLayout 小部件中使用多个 QToolButtons。这些按钮设置为根据分配的默认 QAction 显示图标 + 文本。唯一的问题是内容(图标+文本)总是左对齐的。

内容(图标+文本,在截图中标记为红色框)应位于按钮的中心(由蓝色框表示)。

在大多数情况下,这很好,因为 Qt 会自动尝试以最小尺寸呈现该按钮。但是我正在拉伸按钮以很好地适应我的 QGridLayout。

QToolButton* pButton = new QToolButton(0);
pButton->addDefaultAction(pAction);
pButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
pButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);

QGridLayout *pActionAreaLayout = new QGridLayout;
pActionAreaLayout->addWidget(pSomeOtherWidget, 0, 0, 1, 2);
pActionAreaLayout->addWidget(pButton , 1, 0, 1, 1);

有没有办法强制内容在按钮中居中?

PS:我在another forum 中发现了以下评论,但它似乎颇具侵略性,我还不是很清楚:

您可以尝试使用样式表进行水平对齐,但您可能必须实现 QStyle 代理并为 QStyle::CE_ToolButtonLabel 重新实现 drawControl() 或者从 QToolButton 派生,覆盖 paintEvent() 并为标签以外的所有内容调用样式。

【问题讨论】:

  • 请贴出相关代码
  • @user2672165:我在代码中编辑了问题。不确定在这种情况下是否有帮助......
  • void QGridLayout::​addWidget(QWidget * widget, int row, int column, Qt::Alignment alignment = 0)中使用对齐怎么样?您也可以发布一张图片,说明它的外观以及您希望它的外观,因为需要考虑几个参数?
  • @user2672165 我可能说得不够清楚:网格布局不是问题。按钮位置完美, (almost) 尺寸完美。我遇到的问题是按钮内的内容没有居中。请参阅我添加到问题中的屏幕截图。
  • 好的。我想我明白了。我会尝试修改 pButton->layout()。 QToolButton 应该有一个 QHBoxLayout。

标签: qt qt5 text-alignment qstyle qstylesheet


【解决方案1】:

正如我在回答您另一个问题时所建议的那样。 https://stackoverflow.com/a/28630318/1917249不要使用QToolButton,只使用QPushButton,如果需要,添加弹出菜单。

那么您将不会有不同大小的 QToolButtonQPushButton 小部件。您将拥有居中的图标和文本。

Popupmenu 可以很容易地添加到 QPushButton 中(不会显示小箭头)

QPushButton *pushButton = new QPushButton(toolAction->icon(), "PushButton", window);
// window - widget where button is placed ( to get correct QMenu position )
QObject::connect(pushButton, &QPushButton::released, [window, pushButton, action](){
    QMenu menu;
    menu.addAction(action);
    QPoint pos = window->mapToGlobal(pushButton3->pos());
    pos += QPoint(0, pushButton->height());
    menu.exec(pos);
 });

或者您可以继承QPushButton 并在那里添加弹出菜单处理。然后尝试在QToolButton 中将带有图标的文本居中或具有相同大小的QPushButtonQToolButton 会更好

复杂的例子请看我的回答:https://stackoverflow.com/a/28630318/1917249

【讨论】:

  • 尝试使用 QToolButton 而不是 QPushButton 的原因是 QToolButton 自动接管动作属性(标题文本 + 图标)并处理信号/插槽链接。但最终这些好处不值得我在按钮高度和文本/图标对齐方面经历的麻烦和缺点。因此,我切换到 QPushButton 并手动设置文本/图标属性并设置插槽/信号链接。
【解决方案2】:

以下课程为我完成了这项工作:

class CenteredToolButtonStyle : public QProxyStyle
{
Q_OBJECT

public:
CenteredToolButtonStyle(QToolButton* b, const QSize& sIcon);

virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int, const QPixmap &pixmap) const
    override { m_pic = pixmap; m_ny = rect.y(); Draw(painter); }
virtual void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled,
    const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const override;
void Draw(QPainter *painter) const;

const QToolButton* B;
const QSize SICON;
mutable QString m_s;
mutable QPixmap m_pic;
mutable QRect m_r;
mutable int m_nf, m_ny;
mutable bool m_bEnabled;
mutable QPalette m_pal;
mutable QPalette::ColorRole m_textRole;
};


CenteredToolButtonStyle::CenteredToolButtonStyle(QToolButton* b, const QSize& sIcon)
: QProxyStyle(), B(b), SICON(sIcon), m_nf(0), m_bEnabled(true), m_ny(0)
{
b->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
setParent(b);
}

void CenteredToolButtonStyle::drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal,
bool enabled, const QString &text, QPalette::ColorRole textRole/* = QPalette::NoRole*/) const
{
m_s = text;
m_r = rect;
m_nf = flags | Qt::AlignCenter;
m_bEnabled = enabled;
m_pal = pal;
m_textRole = textRole;
Draw(painter);
}

void CenteredToolButtonStyle::Draw(QPainter *painter) const
{
if (m_ny) {
    if (m_r.y() != m_ny) return;
    auto r = m_r;
    r.adjust(-SICON.width() - 8, m_ny = 0, -itemTextRect(B->fontMetrics(), m_r, m_nf, m_bEnabled, m_s).width(), 0);
    QProxyStyle::drawItemPixmap(painter, r, Qt::AlignCenter, m_pic);
}
QProxyStyle::drawItemText(painter, m_r, m_nf, m_pal, m_bEnabled, m_s, m_textRole);
}

使用示例:

foreach(auto b, ui.mainToolBar->findChildren<QToolButton*>()) 
    b->setStyle(new CenteredToolButtonStyle(b, ui.mainToolBar->iconSize()));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-04
    • 2014-10-22
    • 2016-04-24
    • 1970-01-01
    • 2020-08-21
    • 2021-12-07
    • 2019-07-09
    • 1970-01-01
    相关资源
    最近更新 更多