c++ - 是否可以使用 QT 制作一个 2 面按钮?

标签 c++ qt qt5

我想制作一个双面按钮,如下图所示。当用户悬停时,两种颜色应该切换一侧(左侧变为红色,右侧变为蓝色)。

到目前为止,我的想法是我可以在 Q 按钮内添加 2 个标签,但这似乎不起作用,因为按钮大小不正确并且悬停效果似乎不起作用。

请注意,右侧旨在小于左侧。

/image/OsCj8.png

相反,我得到了这个....

https://i.imgur.com/cE3yXc8.png

这是我当前的代码。

自定义按钮.h

#ifndef CUSTOMBUTTON_H
#define CUSTOMBUTTON_H

#include <QWidget>

class CustomButton : public QWidget
{
    Q_OBJECT
public:
    explicit CustomButton(QWidget *parent = nullptr);

signals:

public slots:
};

#endif // CUSTOMBUTTON_H

自定义按钮.cpp

#include "custombutton.h"

#include <QLabel>
#include <QPushButton>

CustomButton::CustomButton(
        QWidget *parent) :
    QWidget(parent)
{
    QPushButton* button = new QPushButton(this);
    button->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
    button->setGeometry(10, 20, geometry().width(), geometry().height());
    button->setCursor(Qt::PointingHandCursor);

    QLabel* left = new QLabel("Left", button);
    QLabel* right = new QLabel("Right", button);

    left->setStyleSheet("QLabel { "
                        "background-color:blue;"
                        "padding: 30px;"
                        "}"
                        "QButton:hover QLabel {"
                        "background-color:red;"
                        "}");
    right->setStyleSheet("QLabel { "
                         "background-color:red;"
                         "padding: 10px;"
                         "}"
                         "QButton:hover QLabel {"
                         "background-color:blue;"
                         "}");

    button->adjustSize();
}

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "custombutton.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    CustomButton* custom = new CustomButton(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

主窗口.ui

<?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"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

最佳答案

第一种情况你要重构CustomButton类,我不明白为什么要继承QWidget,可以直接继承QPushButton。

另一方面,要使两个 QLabel 占据等距部分,必须使用 QHBoxLayout

QLabels 必须有一个 Alignment Qt::AlignCenter

qss不能做多层次的条件判断,只能处理伪状态,例如下面的代码:

"QButton:hover QLabel {"
    "background-color:blue;"
"}" 

即使将QButton更正为QPushButton,当您将鼠标输入按钮时,QLabel也不会改变。

为了处理更改,我将使用事件 enterEventleaveEvent

如果您希望正确的项目具有相同的宽度,您应该始终使用 setFixedWidth()

代码:

自定义按钮.h

#ifndef CUSTOMBUTTON_H
#define CUSTOMBUTTON_H

#include <QLabel>
#include <QPushButton>

class CustomButton : public QPushButton
{
    Q_OBJECT
public:
    explicit CustomButton(QWidget *parent = nullptr);
protected:
    void enterEvent(QEvent *event);
    void leaveEvent(QEvent *event);
private:
    QLabel left;
    QLabel right;
    const QString leftqss = "QLabel { "
                            "background-color:blue;"
                            "}";
    const QString rightqss = "QLabel { "
                             "background-color:red;"
                             "}";
};


#endif // CUSTOMBUTTON_H

自定义按钮.cpp

#include "custombutton.h"

#include <QVBoxLayout>

CustomButton::CustomButton(QWidget *parent) : QPushButton(parent)
{
    move(10, 20);
    setCursor(Qt::PointingHandCursor);
    right.setFixedWidth(50);

    left.setText("Left");
    right.setText("Right");
    left.setAlignment(Qt::AlignCenter);
    right.setAlignment(Qt::AlignCenter);

    QHBoxLayout *hlay = new QHBoxLayout(this);

    hlay->addWidget(&left);
    hlay->addWidget(&right);
    hlay->setContentsMargins(0, 0, 0, 0);
    hlay->setSpacing(0);

    left.setStyleSheet(leftqss);
    right.setStyleSheet(rightqss);

    left.adjustSize();
    right.adjustSize();
}

void CustomButton::enterEvent(QEvent *event)
{
    left.setStyleSheet(rightqss);
    right.setStyleSheet(leftqss);
    QPushButton::enterEvent(event);
}

void CustomButton::leaveEvent(QEvent *event)
{
    left.setStyleSheet(leftqss);
    right.setStyleSheet(rightqss);
    QPushButton::leaveEvent(event);
}

主窗口.cpp

...
CustomButton* custom = new CustomButton(this);
// Stable a new width to visualize that the right item always has the same width
custom->resize(200, custom->height()); 
... 

enter image description here

您可以在下面的link中找到完整的代码.

关于c++ - 是否可以使用 QT 制作一个 2 面按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50570554/

相关文章:

C++:将未知 union 传递给函数作为参数

C++获取编译代码中使用的一部分代码的大小

c++ - 使用 Qt connect 时 Visual Studio 发出警告

qt - QML 如何获取 ListView 中的当前元素索引?

qt - RCC : Error in 'resource.qrc' : Cannot find file '*.png'

c++ - 哪个是最佳实践?在 C++ 文件或头文件中定义字符串?

c++ - 在 C++11 中有一个基于反范围的 for 吗?

c++ - 使用 Qt 绘制抛物线或任何其他多项式

qt - 如何在另一个应用程序中使用 QT QML C++ 插件?

c++ - 删除框架图时 Qt3D 崩溃