4

我在自定义QGridLayout小部件中使用多个QToolButton。这些按钮设置为根据分配的默认 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:我在另一个论坛中发现了以下评论,但这似乎很有侵略性,对我来说还不是很清楚:

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

4

2 回答 2

3

As I suggest in answer to you another question. https://stackoverflow.com/a/28630318/1917249 Do not use QToolButton, just use QPushButton, and add popup menu if needed.

Then you wont have different sizes of QToolButton and QPushButton widgets. And you will have centered icon and text.

Popupmenu can be easily added to QPushButton ( only small arrow wont be shown )

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

Or you can subclass QPushButton and add Popup menu handling there. Much better then try to center text with icon in QToolButton or have in same size of QPushButton and QToolButton

For complex example please see my answer: https://stackoverflow.com/a/28630318/1917249

于 2015-02-20T13:51:18.430 回答
1

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

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()));
于 2018-09-26T22:57:49.467 回答