我想显示一个按钮,它具有按钮的标准功能(QPushButton),但同时具有不同的外观
但是由于某种原因,他们不允许推断从 QPushButton 继承的类
这是代码(我无法弄清楚我做错了什么):
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(myButton VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)
set(PROJECT_SOURCES
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
custombutton.cpp
custombutton.h
lineitem.cpp
lineitem.h
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(myButton
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET myButton APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(myButton SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(myButton
${PROJECT_SOURCES}
)
endif()
endif()
target_link_libraries(myButton PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(myButton PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(myButton)
endif()
主文件
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
主窗口.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
_line = new lineItem(this);
ui->setupUi(this);
ui->gridLayout->addItem(_line);
}
MainWindow::~MainWindow()
{
delete ui;
}
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "lineitem.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
lineItem* _line;
};
#endif // MAINWINDOW_H
自定义按钮.cpp
#include "custombutton.h"
customButton::customButton(QPushButton *parent)
: QPushButton{parent}
{
_myPushButton = qobject_cast<QPushButton*>(parent);
}
void customButton::setPosition(float radiusPos, float angle)
{
if(radiusPos<0)
_rPos = 0;
else
_rPos = radiusPos;
if(angle>360)
_angle = 360;
else if(radiusPos<0)
_angle = 0;
else
_angle = angle;
_myPushButton->update();
}
QPointF customButton::getCenterPoint(float radPos, float angle)
{
float r = getRadius(_myPushButton->rect());
float xx=cos(qDegreesToRadians(angle+90))*r;
float yy=sin(qDegreesToRadians(angle+90))*r;
QPointF pt;
xx=_myPushButton->rect().center().x()-xx*radPos;
yy=_myPushButton->rect().center().y()-yy*radPos;
pt.setX(xx);
pt.setY(yy);
return pt;
}
void customButton::setColors(const QColor &substrate, const QColor &item, const QColor &outline)
{
_colorSubstrate = substrate;
_colorItem = item;
_colorOutline = outline;
}
void customButton::setValueRange(float minValue, float maxValue)
{
_minValue = minValue;
_maxValue = maxValue;
}
void customButton::setDegreeRange(float minDegree, float maxDegree)
{
_minDegree = minDegree;
_maxDegree = maxDegree;
}
void customButton::setSubstrate(bool val)
{
_drawSubstrate = val;
}
void customButton::setThicknessOutline(float val)
{
_thicknessOutline = val;
}
void customButton::setOutline(bool val)
{
_drawOutline = val;
}
void customButton::setShadow(bool val)
{
_drawShadow = val;
}
float customButton::getRadius(const QRectF &tmpRect)
{
float r = 0;
if(tmpRect.width() < tmpRect.height()*_wh)
r = tmpRect.width()/(2.0*_wh);
else
r = tmpRect.height()/2.0;
return r;
}
float customButton::getDegFromValue(float val)
{
float a = (_maxDegree-_minDegree)/(_maxValue-_minValue);
float b = -a*_minValue+_minDegree;
return a*val+b;
}
void customButton::setScaleFactor(float val)
{
_scaleFactor = val;
}
void customButton::setThickness(float val)
{
_thickness = val;
}
void customButton::setProportions(float wh)
{
_wh = wh;
}
自定义按钮.h
#ifndef BUTTONITEM_H
#define BUTTONITEM_H
#include <QObject>
#include <QButtonGroup>
#include <QPushButton>
#include <QPainter>
#include <QColor>
#include <QFont>
#include <QDebug>
#include <QPainterPath>
#include <QPointF>
#include <QRect>
#include <QGraphicsBlurEffect>
#include <QGraphicsItem>
#include <QtMath>
#include <QMessageBox>
class customButton : public QPushButton
{
public:
explicit customButton(QPushButton *parent = nullptr);
virtual void draw(QPainter *p) = 0;
///
/// \brief setPosition установить радиус (1=100%) и угол (в градусах) определяющий расположение item на виджете
///
void setPosition(float radiusPos , float angle);
///
/// \brief getPoint расчитать центральную точку
///
QPointF getCenterPoint(float radPos, float angle);
///
/// \brief setColors: установить три цвета ( подложки, основной и обводки) для item
///
void setColors(const QColor &substrate, const QColor &item, const QColor &outline);
///
/// \brief setValueRange установить диапазон изменения значения
///
void setValueRange(float minValue,float maxValue);
///
/// \brief setDegreeRange установить диапазон изменения угла
///
void setDegreeRange(float minDegree,float maxDegree);
/// inner function
///
/// \brief включить отрисовку подложки с заданным ранее цветом и прозрачностью
///
void setSubstrate(bool val);
///
/// \brief setThicknessOutline установить толщину обводки
///
void setThicknessOutline(float val);
///
/// \brief включить отрисовку подложки с заданным ранее цветом и прозрачностью
///
void setOutline(bool val);
///
/// \brief включить отрисовку "тени"
///
void setShadow(bool val);
///
/// \brief getRadius получить радиус окружности в которую вписан заданный прямоугольник
///
float getRadius(const QRectF &tmpRect);
///
/// \brief getDegFromValue
///
float getDegFromValue(float val);
///
/// \brief setScaleFactor установить коэффициент масштаба
///
void setScaleFactor(float val);
///
/// \brief setThickness установить толщину линии
///
void setThickness(float val);
///
/// \brief setProportions задать соотношение ширины к высоте в виджете с данным item
///
void setProportions(float wh);
// QWidget *_parentWidget;
QPushButton *_myPushButton;
QColor _colorSubstrate {Qt::black};
QColor _colorItem {Qt::black};
QColor _colorOutline {Qt::white};
QColor _colorCornerBound {Qt::darkRed};
QColor _colorShadowB {Qt::black};
QColor _colorShadowW {Qt::white};
QColor _colorKaracurtWhite {255, 255, 255, 255};
QColor _colorKaracurtYellow {255, 255, 0 , 255};
QColor _colorKaracurtSubstrate { 0, 0, 0 , 128};
QColor _colorKaracurtShadow { 0 , 0 , 0 , 200};
float _thicknessOutline {5};
float _thickness {3};
float _scaleFactor {1};
float _rPos {0.5};
float _angle {0.5};
float _minValue {0};
float _maxValue {100};
float _minDegree {0};
float _maxDegree {360};
bool _drawSubstrate {false};
bool _drawOutline {false};
bool _drawShadow {false};
float _wh {1};
signals:
};
#endif // BUTTONITEM_H
lineitem.cpp
#include "lineitem.h"
lineItem::lineItem(QPushButton *parent)
: customButton(parent)
{
}
void lineItem::draw(QPainter *p)
{
p->save();
QPointF center = getCenterPoint(_rPos, _angle);
float r = getRadius(_myPushButton->rect())*_scaleFactor;
if(_drawSubstrate)
{
p->setBrush(QBrush(_colorSubstrate));
p->drawEllipse(center,(int)(r), (int)(r));
}
p->translate(center);
p->setPen(Qt::NoPen);
p->setBrush(QBrush(_color));
p->drawRect(-r/1.5, -r/1.5, r*1.34, r*1.34);
QVector<QPointF> tmpPoints;
tmpPoints.append(QPointF(0.0 - r*0.46 , 0.0 + r*0.2 ));
tmpPoints.append(QPointF(0.0 - r*0.36 , 0.0 + r*0.2 ));
tmpPoints.append(QPointF(0.0 - r*0.26 , 0.0 - r*0.15 ));
tmpPoints.append(QPointF(0.0 - r*0.06 , 0.0 + r*0.45 ));
tmpPoints.append(QPointF(0.0 + r*0.06 , 0.0 - r*0.4 ));
tmpPoints.append(QPointF(0.0 + r*0.26 , 0.0 + r*0.25 ));
tmpPoints.append(QPointF(0.0 + r*0.36 , 0.0 + r*0.1 ));
tmpPoints.append(QPointF(0.0 + r*0.46 , 0.0 + r*0.1 ));
QPainterPath path;
path.addPolygon(tmpPoints);
p->setBrush(Qt::NoBrush);
p->setPen(QPen(_color_line, 2*_thickness, Qt::SolidLine));
p->drawPath(path);
p->restore();
}
lineitem.h
#ifndef LINEITEM_H
#define LINEITEM_H
#include "custombutton.h"
class lineItem : public customButton
{
public:
lineItem();
explicit lineItem(QPushButton *parent = nullptr);
virtual void draw(QPainter * p) override final;
private:
QColor _color {220, 0, 0, 227};
QColor _color_line {255,255,255,255};
};
#endif // LINEITEM_H
这是一个很好的答案:
https://blog.altuninvv.ru/programming/qt5/widgets/153-create-slider-slider-slider-button-in-qt5
这是一个例子:
CMakeLists.txt
主文件
主窗口.h
主窗口.cpp
qsliderbutton.h
qsliderbutton.cpp