Qt QPushButton图标左对齐,文本居中
在我的Qt5.7.1应用程序中,我有一些按钮,我想将按钮的图标与左侧和中间文本对齐,但在designer中没有这样做的选项 通过向按钮样式表添加以下代码,我可以将图标和文本左对齐: 文本对齐:左对齐 但这不是我想要实现的。Qt QPushButton图标左对齐,文本居中,qt,alignment,leftalign,Qt,Alignment,Leftalign,在我的Qt5.7.1应用程序中,我有一些按钮,我想将按钮的图标与左侧和中间文本对齐,但在designer中没有这样做的选项 通过向按钮样式表添加以下代码,我可以将图标和文本左对齐: 文本对齐:左对齐 但这不是我想要实现的。 所以,你们能告诉我,若有任何选项,使图标向左对齐,并保持文本居中对齐?谢谢您的帮助。要获得这种级别的控制,您需要编写一些代码来覆盖平台的样式。这最好用一个简单的方法来完成。在本例中,我们正在寻找样式何时被要求绘制CE_PushButtonLabel(标签包括图标,它们在Q
所以,你们能告诉我,若有任何选项,使图标向左对齐,并保持文本居中对齐?谢谢您的帮助。要获得这种级别的控制,您需要编写一些代码来覆盖平台的样式。这最好用一个简单的方法来完成。在本例中,我们正在寻找样式何时被要求绘制CE_PushButtonLabel(标签包括图标,它们在Qt中硬编码以对齐) 您需要实现并重写该方法。它的大部分代码直接从默认drawcontrol方法(in)的Qt源代码复制而来——因此,尽管它看起来很长,但大部分都在做Qt已经做过的事情。我在修改的部分周围添加了额外的/**/marker。这不会出现在Qt设计器中,但会在运行时起作用 最终结果(显示在mac上,应与您所在的平台匹配) main.cpp:
QApplication a(argc, argv);
a.setStyle(new MyStyle);
...
我的风格
class MyStyle : public QProxyStyle
{
public:
virtual void drawControl(ControlElement element, const QStyleOption *opt,
QPainter *p, const QWidget *widget = Q_NULLPTR) const;
};
mystyle.cpp
// Copied from Qt source code..
static QWindow *qt_getWindow(const QWidget *widget)
{
return widget ? widget->window()->windowHandle() : 0;
}
void MyStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *widget) const
{
if(element==CE_PushButtonLabel)
{
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt))
{
QRect textRect = button->rect;
uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
if (!proxy()->styleHint(SH_UnderlineShortcut, button, widget))
tf |= Qt::TextHideMnemonic;
if (!button->icon.isNull()) {
QRect iconRect;
QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
if (mode == QIcon::Normal && button->state & State_HasFocus)
mode = QIcon::Active;
QIcon::State state = QIcon::Off;
if (button->state & State_On)
state = QIcon::On;
QPixmap pixmap = button->icon.pixmap(qt_getWindow(widget), button->iconSize, mode, state);
int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio();
int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio();
int labelWidth = pixmapWidth;
int labelHeight = pixmapHeight;
int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
if (!button->text.isEmpty())
labelWidth += (textWidth + iconSpacing);
/*************************************************************/
// Make the icon rectangle always be 10px in from the left edge
/*************************************************************/
iconRect = QRect(10,
textRect.y() + (textRect.height() - labelHeight) / 2,
pixmapWidth, pixmapHeight);
iconRect = visualRect(button->direction, textRect, iconRect);
/***********************************/
// Always horizontal align the text
/***********************************/
tf |= Qt::AlignHCenter;
if (button->state & (State_On | State_Sunken))
iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
p->drawPixmap(iconRect, pixmap);
} else {
tf |= Qt::AlignHCenter;
}
if (button->state & (State_On | State_Sunken))
textRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
if (button->features & QStyleOptionButton::HasMenu) {
int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget);
if (button->direction == Qt::LeftToRight)
textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
else
textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
}
proxy()->drawItemText(p, textRect, tf, button->palette, (button->state & State_Enabled),
button->text, QPalette::ButtonText);
}
return;
}
// For all other controls, draw the default
QProxyStyle::drawControl(element, opt, p, widget);
}
//从Qt源代码复制的。。
静态QWindow*qt_getWindow(常量QWidget*widget)
{
返回widget?widget->window()->windowHandle():0;
}
void MyStyle::drawControl(ControlElement元素,常量QStyleOption*opt,qPaint*p,常量QWidget*widget)常量
{
if(元素==CE\u按钮标签)
{
如果(常量QStyleOptionButton*button=qstyleoption_cast(opt))
{
QRect textRect=按钮->矩形;
uint tf=Qt::AlignVCenter | Qt::textshowmemonic;
if(!proxy()->styleHint(SH_UnderlineShortcut、按钮、小部件))
tf |=Qt::TextHideMnemonic;
如果(!按钮->图标.isNull()){
QRect-iconRect;
QIcon::Mode Mode=按钮->状态和状态\已启用?QIcon::正常:QIcon::已禁用;
if(mode==QIcon::Normal&&button->state&state\u HasFocus)
模式=QIcon::活动;
QIcon::State State=QIcon::Off;
如果(按钮->状态和状态打开)
state=QIcon::On;
QPixmap=button->icon.pixmap(qt_getWindow(小部件),button->iconSize,mode,state);
int pixmapWidth=pixmap.width()/pixmap.devicePixelRatio();
int pixmapHeight=pixmap.height()/pixmap.devicePixelRatio();
int labelWidth=pixmapWidth;
int-labelHeight=像素高度;
int iconSpacing=4;/####4当前在QPushButton::sizeHint()中硬编码
int textWidth=button->fontMetrics.boundingRect(opt->rect,tf,button->text).width();
如果(!button->text.isEmpty())
labelWidth+=(文本宽度+图标对齐);
/*************************************************************/
//使图标矩形始终距离左边缘10px英寸
/*************************************************************/
iconRect=QRect(10,
textRect.y()+(textRect.height()-labelHeight)/2,
pixmapWidth,pixmapHeight);
iconRect=visualRect(按钮->方向、文本Rect、iconRect);
/***********************************/
//始终水平对齐文本
/***********************************/
tf |=Qt::AlignHCenter;
如果(按钮->状态&(状态|状态|凹陷))
iconRect.translate(proxy()->pixelMetric(PM_按钮shifthorizontal,opt,widget),
proxy()->pixelMetric(PM_按钮shiftvertical、opt、widget));
p->drawPixmap(iconRect,pixmap);
}否则{
tf |=Qt::AlignHCenter;
}
如果(按钮->状态&(状态|状态|凹陷))
text rect.translate(proxy()->pixelMetric(PM_按钮shifthorizontal,opt,widget),
proxy()->pixelMetric(PM_按钮shiftvertical、opt、widget));
如果(按钮->功能和QStyleOptionButton::HASSMENU){
int indicatorSize=proxy()->pixelMetric(PM_菜单按钮指示器、按钮、小部件);
如果(按钮->方向==Qt::LeftToRight)
textRect=textRect.adjusted(0,0,-指示符化,0);
其他的
textRect=textRect.adjusted(指示符号化,0,0,0);
}
proxy()->drawItemText(p、textRect、tf、按钮->调色板,(按钮->状态和状态启用),
按钮->文本,QPalette::ButtonText);
}
返回;
}
//对于所有其他控件,绘制默认值
QProxyStyle::drawControl(元素、选项、p、小部件);
}
在不破坏用户界面风格的情况下减少代码量
pushButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion));
pushButton->setStyleSheet("text-align:left;");
pushButton->setLayout(new QGridLayout);
QLabel* textLabel = new QLabel("Hello world!");
textLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); // or center
textLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true);
pushButton->layout()->addWidget(textLabel);
请记住将setText信号发送到textLabel而不是按钮,只需按照cbuchart的建议专门化
QPushButton
并覆盖paintEvent
和sizeHint
。然后将其用作常规的QPushButton
MyButton
声明和实施:
mybutton.h:
#pragma once
#include <QPushButton>
class MyButton : public QPushButton
{
public:
explicit MyButton(QWidget* parent = nullptr);
virtual ~MyButton();
void setPixmap(const QPixmap& pixmap);
virtual QSize sizeHint() const override;
protected:
virtual void paintEvent(QPaintEvent* e) override;
private:
QPixmap m_pixmap;
};
#include "mybutton.h"
#include <QPainter>
MyButton::MyButton(QWidget* parent) : QPushButton(parent)
{
}
MyButton::~MyButton()
{
}
QSize MyButton::sizeHint() const
{
const auto parentHint = QPushButton::sizeHint();
// add margins here if needed
return QSize(parentHint.width() + m_pixmap.width(), std::max(parentHint.height(), m_pixmap.height()));
}
void MyButton::setPixmap(const QPixmap& pixmap)
{
m_pixmap = pixmap;
}
void MyButton::paintEvent(QPaintEvent* e)
{
QPushButton::paintEvent(e);
if (!m_pixmap.isNull())
{
const int y = (height() - m_pixmap.height()) / 2; // add margin if needed
QPainter painter(this);
painter.drawPixmap(5, y, m_pixmap); // hardcoded horizontal margin
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="MyButton" name="button1">
<property name="text">
<string>Button</string>
</property>
</widget>
</item>
<item>
<widget class="MyButton" name="button2">
<property name="text">
<string>Other button</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>MyButton</class>
<extends>QPushButton</extends>
<header>mybutton.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
#pragma once
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QStyle>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStyle* style = qApp->style();
// set buttons pixmaps:
ui->button1->setPixmap( style->standardPixmap(QStyle::SP_ComputerIcon) );
ui->button2->setPixmap( style->standardPixmap(QStyle::SP_TrashIcon) );
}
MainWindow::~MainWindow()
{
delete ui;
}
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
main window.h:
#pragma once
#include <QPushButton>
class MyButton : public QPushButton
{
public:
explicit MyButton(QWidget* parent = nullptr);
virtual ~MyButton();
void setPixmap(const QPixmap& pixmap);
virtual QSize sizeHint() const override;
protected:
virtual void paintEvent(QPaintEvent* e) override;
private:
QPixmap m_pixmap;
};
#include "mybutton.h"
#include <QPainter>
MyButton::MyButton(QWidget* parent) : QPushButton(parent)
{
}
MyButton::~MyButton()
{
}
QSize MyButton::sizeHint() const
{
const auto parentHint = QPushButton::sizeHint();
// add margins here if needed
return QSize(parentHint.width() + m_pixmap.width(), std::max(parentHint.height(), m_pixmap.height()));
}
void MyButton::setPixmap(const QPixmap& pixmap)
{
m_pixmap = pixmap;
}
void MyButton::paintEvent(QPaintEvent* e)
{
QPushButton::paintEvent(e);
if (!m_pixmap.isNull())
{
const int y = (height() - m_pixmap.height()) / 2; // add margin if needed
QPainter painter(this);
painter.drawPixmap(5, y, m_pixmap); // hardcoded horizontal margin
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="MyButton" name="button1">
<property name="text">
<string>Button</string>
</property>
</widget>
</item>
<item>
<widget class="MyButton" name="button2">
<property name="text">
<string>Other button</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>MyButton</class>
<extends>QPushButton</extends>
<header>mybutton.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
#pragma once
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QStyle>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStyle* style = qApp->style();
// set buttons pixmaps:
ui->button1->setPixmap( style->standardPixmap(QStyle::SP_ComputerIcon) );
ui->button2->setPixmap( style->standardPixmap(QStyle::SP_TrashIcon) );
}
MainWindow::~MainWindow()
{
delete ui;
}
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#pragma一次
#包括
名称空间用户界面{
类主窗口;
}
类主窗口:公共QMainWindow
{
Q_对象
公众:
显式主窗口(QWidget*parent=0);
~main窗口();
私人:
Ui::MainWindow*Ui;
};
mainwindow.cpp:
#pragma once
#include <QPushButton>
class MyButton : public QPushButton
{
public:
explicit MyButton(QWidget* parent = nullptr);
virtual ~MyButton();
void setPixmap(const QPixmap& pixmap);
virtual QSize sizeHint() const override;
protected:
virtual void paintEvent(QPaintEvent* e) override;
private:
QPixmap m_pixmap;
};
#include "mybutton.h"
#include <QPainter>
MyButton::MyButton(QWidget* parent) : QPushButton(parent)
{
}
MyButton::~MyButton()
{
}
QSize MyButton::sizeHint() const
{
const auto parentHint = QPushButton::sizeHint();
// add margins here if needed
return QSize(parentHint.width() + m_pixmap.width(), std::max(parentHint.height(), m_pixmap.height()));
}
void MyButton::setPixmap(const QPixmap& pixmap)
{
m_pixmap = pixmap;
}
void MyButton::paintEvent(QPaintEvent* e)
{
QPushButton::paintEvent(e);
if (!m_pixmap.isNull())
{
const int y = (height() - m_pixmap.height()) / 2; // add margin if needed
QPainter painter(this);
painter.drawPixmap(5, y, m_pixmap); // hardcoded horizontal margin
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="MyButton" name="button1">
<property name="text">
<string>Button</string>
</property>
</widget>
</item>
<item>
<widget class="MyButton" name="button2">
<property name="text">
<string>Other button</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>MyButton</class>
<extends>QPushButton</extends>
<header>mybutton.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
#pragma once
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QStyle>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStyle* style = qApp->style();
// set buttons pixmaps:
ui->button1->setPixmap( style->standardPixmap(QStyle::SP_ComputerIcon) );
ui->button2->setPixmap( style->standardPixmap(QStyle::SP_TrashIcon) );
}
MainWindow::~MainWindow()
{
delete ui;
}
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#包括“mainwin”