分段控制器在前端交互使用较为广泛相比 Qt 常用的下拉框、单选框、复选框选择交互上更为便捷样式上更加简洁可控使用 Qt 实现带类似功能的控件可复用到选项需求的功能开发提高软件质量。功能包括选项输入、样式接口、默认选中、互斥检测、结果回传以 https://forgeglobal.com/ 网站的实现为参考。QSegmentedWidget.hclass QSegmentedWidget : public QWidget { Q_OBJECT public: QSegmentedWidget(QWidget *parent nullptr); ~QSegmentedWidget(); bool eventFilter(QObject *watched, QEvent *event); void setSource(QStringList lst, QString ss); void setHoverColor(QString color) { hoverColor color; updateColor(); } void setHoverTextColor(QString color) { hoverTextColor color; updateColor(); } void setCheckColor(QString color) { checkColor color; updateColor(); } private slots: void setChecked(); void updateColor() { btnStyleNormal QString(QPushButton{background-color: rgb(255,255,255);color: rgb(95,110,124); font: 14pt \Microsoft YaHei\; border: 1px solid;border-radius:0px;}QPushButton:hover{background-color: rgb(%1);color: rgb(%2);}).arg(hoverColor).arg(hoverTextColor); btnStyleCheck QString(QPushButton{background-color: rgb(%2);color: rgb(247,249,250); font: 14pt \Microsoft YaHei\; border: 1px solid;border-radius:0px;}QPushButton:hover{background-color: rgb(%1);color: rgb(%3);}).arg(hoverColor).arg(checkColor).arg(hoverTextColor); btnStyleNormalFirst QString(QPushButton{background-color: rgb(255,255,255);color: rgb(95,110,124); font: 14pt \Microsoft YaHei\; border: 1px solid;border-top-left-radius: 5px;border-top-right-radius: 0px;border-bottom-left-radius: 5px;border-bottom-right-radius: 0px;}QPushButton:hover{background-color: rgb(%1);color: rgb(%2);}).arg(hoverColor).arg(hoverTextColor); btnStyleCheckFirst QString(QPushButton{background-color: rgb(%2);color: rgb(247,249,250); font: 14pt \Microsoft YaHei\; border: 1px solid;border-top-left-radius: 5px;border-top-right-radius: 0px;border-bottom-left-radius: 5px;border-bottom-right-radius: 0px;}QPushButton:hover{background-color: rgb(%1);color: rgb(%3);}).arg(hoverColor).arg(checkColor).arg(hoverTextColor); btnStyleNormalLast QString(QPushButton{background-color: rgb(255,255,255);color: rgb(95,110,124); font: 14pt \Microsoft YaHei\; border: 1px solid;border-top-left-radius: 0px;border-top-right-radius: 5px;border-bottom-left-radius: 0px;border-bottom-right-radius: 5px;}QPushButton:hover{background-color: rgb(%1);color: rgb(%2);}).arg(hoverColor).arg(hoverTextColor); btnStyleCheckLast QString(QPushButton{background-color: rgb(%2);color: rgb(247,249,250); font: 14pt \Microsoft YaHei\; border: 1px solid;border-top-left-radius: 0px;border-top-right-radius: 5px;border-bottom-left-radius: 0px;border-bottom-right-radius: 5px;}QPushButton:hover{background-color: rgb(%1);color: rgb(%3);}).arg(hoverColor).arg(checkColor).arg(hoverTextColor); } signals: void emitChecked(QString ss); private: QString hoverColor 30,36,42; QString hoverTextColor 247,249,250; QString checkColor 30,36,42; QStringList sourceLst; QListQPushButton* btnLst; QHBoxLayout *layout nullptr; QString btnStyleNormal; QString btnStyleCheck; QString btnStyleNormalFirst; QString btnStyleCheckFirst; QString btnStyleNormalLast; QString btnStyleCheckLast; QPushButton *curBtn nullptr; QPixmap pixmap; };QSegmentedWidget.cpp#include QSvgRenderer QPixmap svg2Pixmap(QString svg) { QSvgRenderer render; render.load(svg); QPixmap pix(render.defaultSize()); pix.fill(Qt::transparent); QPainter painter(pix); painter.setRenderHints(QPainter::Antialiasing); render.render(painter); return pix; } QSegmentedWidget::QSegmentedWidget(QWidget *parent) : QWidget(parent) { layout new QHBoxLayout; layout-setSpacing(0); setLayout(layout); updateColor(); pixmap svg2Pixmap(check.svg); } QSegmentedWidget::~QSegmentedWidget() { } bool QSegmentedWidget::eventFilter(QObject *watched, QEvent *event) { Q_UNUSED(watched); if (event-type() QEvent::Enter) { setCursor(Qt::PointingHandCursor); return true; } if (event-type() QEvent::Leave) { setCursor(Qt::ArrowCursor); return true; } return false; } void QSegmentedWidget::setSource(QStringList lst, QString cc) { curBtn nullptr; foreach (QPushButton* btn, btnLst) { layout-removeWidget(btn); delete btn; } btnLst.clear(); sourceLst lst; foreach (QString data, lst) { QPushButton *btn new QPushButton(data); btn-setFixedSize(90, 50); btn-setObjectName(data); if (data sourceLst.first()) { btn-setStyleSheet(btnStyleNormalFirst); } else if (data sourceLst.last()) { btn-setStyleSheet(btnStyleNormalLast); } else { btn-setStyleSheet(btnStyleNormal); } btn-installEventFilter(this); connect(btn, SIGNAL(clicked(bool)), this, SLOT(setChecked())); layout-addWidget(btn); btnLst.append(btn); } if (lst.contains(cc)) { foreach (QPushButton* btn, btnLst) { if (btn-objectName() cc) { btn-click(); break; } } } else { btnLst[0]-click(); } } void QSegmentedWidget::setChecked() { QPushButton *btn qobject_castQPushButton *(sender()); if (curBtn btn) { return; } btn-setIcon(QIcon(pixmap)); QString data btn-objectName(); if (data sourceLst.first()) { btn-setStyleSheet(btnStyleCheckFirst); } else if (data sourceLst.last()) { btn-setStyleSheet(btnStyleCheckLast); } else { btn-setStyleSheet(btnStyleCheck); } if (curBtn ! nullptr) { curBtn-setIcon(QIcon()); QString data curBtn-objectName(); if (data sourceLst.first()) { curBtn-setStyleSheet(btnStyleNormalFirst); } else if (data sourceLst.last()) { curBtn-setStyleSheet(btnStyleNormalLast); } else { curBtn-setStyleSheet(btnStyleNormal); } } curBtn btn; emit emitChecked(btn-objectName()); }check.svgsvg xmlnshttp://www.w3.org/2000/svg width14 height14 viewBox0 0 14 14 fillnonepath dM4.33,8.92l-2.92-3.06c-.33-.34-.84-.34-1.17,0-.33.34-.33.88,0,1.22l3.49,3.67c.33.34.85.34,1.18,0L13.76,1.48c.33-.34.33-.88,0-1.22-.33-.34-.84-.34-1.17,0L4.33,8.92Z fill#F7F9FA/path/svgsetSource选项输入和默认选中、set**Color样式接口、emitChecked结果回传。segmentedWidget new QSegmentedWidget; connect(segmentedWidget, SIGNAL(emitChecked(QString)), this, SLOT(segmentedChecked(QString))); QStringList lst; lst.append(7D); lst.append(1M); lst.append(3M); lst.append(6M); lst.append(1Y); lst.append(ALL); segmentedWidget-setSource(lst, 6M); void MainWindow::segmentedChecked(QString cc) { qDebug() cc; } QStringList lst; lst.append(Mon); lst.append(Tue); lst.append(Wed); lst.append(Thu); lst.append(Fri); lst.append(Sat); lst.append(Sun); segmentedWidget-setHoverColor(64,158,255); segmentedWidget-setHoverTextColor(96,98,102); segmentedWidget-setCheckColor(64,158,255); segmentedWidget-setSource(lst, Wed);