带图标+文字的QToolButton:如何将两者都集中在一起?

时间:2015-02-14 13:16:57

标签: qt qt5 text-alignment qstyle qstylesheet

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

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

enter image description here

对于大多数情况,这很好,因为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()并为标签以外的所有内容调用样式。

2 个答案:

答案 0 :(得分:2)

正如我建议你回答另一个问题。 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

答案 1 :(得分:0)

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

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()));