QPushButton icon aligned left with text centered

后端 未结 3 1179
悲&欢浪女
悲&欢浪女 2020-12-17 14:21

In my Qt 5.7.1 application I\'ve some buttons, I want to align button\'s icons to left and centre text, but there is no option in designer to do this.

I can

3条回答
  •  轮回少年
    2020-12-17 14:37

    Simply specialize QPushButton and override paintEvent and sizeHint, as proposed by cbuchart here. Then use it as a regular QPushButton.

    MyButton declaration and implementation:

    mybutton.h:

    #pragma once
    
    #include 
    
    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;
    };
    

    mybutton.cpp:

    #include "mybutton.h"
    
    #include 
    
    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
        }
    }
    

    Exemple of usage:

    Here is an example where "Promote widget" feature in Qt Designer was used to create MyButton from .ui files:

    mainframe.ui:

    
    
     MainWindow
     
      
       
        0
        0
        400
        300
       
      
      
       MainWindow
      
      
       
        
         
          
           Button
          
         
        
        
         
          
           Other button
          
         
        
       
      
      
       
        
         0
         0
         400
         20
        
       
      
      
       
        TopToolBarArea
       
       
        false
       
      
      
     
     
     
      
       MyButton
       QPushButton
       
    mybutton.h

    mainwindow.h:

    #pragma once
    
    #include 
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    

    mainwindow.cpp:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include 
    
    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;
    }
    

    main.cpp:

    #include "mainwindow.h"
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    Results in:

    • Compared to docsteer answer, this solution makes it possible to apply the new style to only some buttons of your project. And the code is also smaller.
    • Compared to IGHOR answer, you can still use the button as a regular QPushButton (using QPushButton::setText), you don't need to keep a reference to a mockup QLabel to change button's text.

提交回复
热议问题