像 QToolButton 一样的办公室
Office like QToolButton
我目前正在尝试使 QToolButton 看起来与 Office 中的等效。
它应该是这样的:
我知道我可以使用 QToolButton::menu-button 访问菜单按钮,但是 QToolButton::menu-button:hover 与 QToolButton:hover 相同,所以我不能区分两者,我可以' 为 QToolButton::menu 按钮设置边框。有什么想法吗?
您可以创建类似拆分按钮的东西。
class SplitButton : public QPushButton
{
Q_OBJECT
public:
explicit SplitButton(QWidget *parent = 0);
void setMenu(QMenu* menu);
protected:
void resizeEvent ( QResizeEvent * );
void mousePressEvent ( QMouseEvent * );
private:
QFrame* line;
};
增加了通过setMenu()
方法插入菜单的机会。 QFrame
需要分离按钮和弹出菜单。
在构造函数中只初始化基class:
#include <QFrame>
#include <QMenu>
#include <QResizeEvent>
SplitButton::SplitButton(QWidget *parent):
QPushButton(parent)
{
}
弹出菜单将添加如下:
void SplitButton::setMenu( QMenu* menu )
{
if (menu) {
line = new QFrame(this);
line->setFrameShape(QFrame::VLine);
line->setFrameShadow(QFrame::Sunken);
QPushButton::setMenu(menu);
connect(menu, &QMenu::triggered, [=](QAction *act) {
setText(act->text());
});
}
}
如您所见,我们使用了 QPushButton::setMenu()
method and connect menu triggered signal to slot, realized with labda, so you need include c++11 compatibility。
在我们需要覆盖resize、mousePress 和keyPressed 事件之后。作为最小的例子,我做了第二个。
void SplitButton::resizeEvent ( QResizeEvent * event )
{
if (menu()) {
int width = event->size().width();
int height = event->size().height();
line->setGeometry(QRect(width - 18, 4, 3, height - 8));
}
}
如果菜单可用,在调整大小事件中,我们为伪按钮添加偏移量的帧。
void SplitButton::mousePressEvent( QMouseEvent * event )
{
if (menu()) {
if ( width()-event->x() <= 15 )
showMenu();
else
setDown(true);
} else {
QPushButton::mousePressEvent(event);
}
}
对于 mousePress 事件,我们只是 select 我们想要做的事情:显示菜单或按钮。
用法:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), m_file(QString())
{
setupUi(this);
SplitButton *split = new SplitButton;
split->setText("B");
QMenu *menu = new QMenu;
menu->addAction("Y");
menu->addAction("B");
menu->addAction("U");
split->setMenu(menu);
split->setCheckable(true);
Ui::MainWindow::mainToolBar->addWidget(split);
}
并且您可以为类似 Office 的效果设置按钮 chechable。
这只是其中一种可能的实现方式,希望对您有所帮助。
我在屏幕上的样子:
当然,这不是最终结果,您需要根据需要重新绘制或使用 styles 进行平面样式。
我目前正在尝试使 QToolButton 看起来与 Office 中的等效。
它应该是这样的:
我知道我可以使用 QToolButton::menu-button 访问菜单按钮,但是 QToolButton::menu-button:hover 与 QToolButton:hover 相同,所以我不能区分两者,我可以' 为 QToolButton::menu 按钮设置边框。有什么想法吗?
您可以创建类似拆分按钮的东西。
class SplitButton : public QPushButton
{
Q_OBJECT
public:
explicit SplitButton(QWidget *parent = 0);
void setMenu(QMenu* menu);
protected:
void resizeEvent ( QResizeEvent * );
void mousePressEvent ( QMouseEvent * );
private:
QFrame* line;
};
增加了通过setMenu()
方法插入菜单的机会。 QFrame
需要分离按钮和弹出菜单。
在构造函数中只初始化基class:
#include <QFrame>
#include <QMenu>
#include <QResizeEvent>
SplitButton::SplitButton(QWidget *parent):
QPushButton(parent)
{
}
弹出菜单将添加如下:
void SplitButton::setMenu( QMenu* menu )
{
if (menu) {
line = new QFrame(this);
line->setFrameShape(QFrame::VLine);
line->setFrameShadow(QFrame::Sunken);
QPushButton::setMenu(menu);
connect(menu, &QMenu::triggered, [=](QAction *act) {
setText(act->text());
});
}
}
如您所见,我们使用了 QPushButton::setMenu()
method and connect menu triggered signal to slot, realized with labda, so you need include c++11 compatibility。
在我们需要覆盖resize、mousePress 和keyPressed 事件之后。作为最小的例子,我做了第二个。
void SplitButton::resizeEvent ( QResizeEvent * event )
{
if (menu()) {
int width = event->size().width();
int height = event->size().height();
line->setGeometry(QRect(width - 18, 4, 3, height - 8));
}
}
如果菜单可用,在调整大小事件中,我们为伪按钮添加偏移量的帧。
void SplitButton::mousePressEvent( QMouseEvent * event )
{
if (menu()) {
if ( width()-event->x() <= 15 )
showMenu();
else
setDown(true);
} else {
QPushButton::mousePressEvent(event);
}
}
对于 mousePress 事件,我们只是 select 我们想要做的事情:显示菜单或按钮。
用法:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), m_file(QString())
{
setupUi(this);
SplitButton *split = new SplitButton;
split->setText("B");
QMenu *menu = new QMenu;
menu->addAction("Y");
menu->addAction("B");
menu->addAction("U");
split->setMenu(menu);
split->setCheckable(true);
Ui::MainWindow::mainToolBar->addWidget(split);
}
并且您可以为类似 Office 的效果设置按钮 chechable。
这只是其中一种可能的实现方式,希望对您有所帮助。
我在屏幕上的样子:
当然,这不是最终结果,您需要根据需要重新绘制或使用 styles 进行平面样式。