我目前正在使用Qt 5.7,并且已经将QPushButton子类化,其基本思想是在Qt Style sheets上使用QML side。这是头文件:
#ifndef LTPUSHBUTTON_H
#define LTPUSHBUTTON_H
#include <QWidget>
#include <QPushButton>
#include <QString>
/**
* @class Modified push button class
*/
class LtPushButton : public QPushButton
{
Q_OBJECT
public:
/**
* @brief Constructor
* @param parent
*/
LtPushButton(const QString& ltText=QString(),
QWidget* const parent=Q_NULLPTR);
/**
* @brief Method for settings CSS style from QML side
* @param ltCSSStyle
*/
Q_INVOKABLE void ltSetCSSStyle(const QString& ltCSSStyle);
};
#endif // LTPUSHBUTTON_H
及其实现:
#include "ltpushbutton.h"
LtPushButton::LtPushButton(const QString <Text,
QWidget* const parent)
: QPushButton(parent)
{
this->setText(ltText);
} // constructor
void LtPushButton::ltSetCSSStyle(const QString& ltCSSStyle)
{
this->setStyleSheet(ltCSSStyle);
} // ltSetCSSStyle
LtPushButton
类型已在main.cpp中注册:
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include "ltpushbutton.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<LtPushButton>("com.testapp.gui",
1,
0,
"LtPushButton");
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
,当我尝试在main.qml
中设置窗口的样式表时:
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import com.testapp.gui 1.0
Window
{
width: 640
height: 480
visible: true
title: qsTr("Hello World")
color: "red"
GridLayout
{
anchors.fill: parent
rows: 2
columns: 2
LtPushButton
{
id: ltUpperLeftButton
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter|Qt.AlignVCenter
text: qsTr("One");
} // LtPushButton
Component.onCompleted:
{
ltUpperLeftButton.ltSetCSSStyle("border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background-color: #0047bd;
border: 2px solid #0047bd;
color: #ffffff;
outline: none;");
} // Component.onCompleted
} // GridLayout
} // Window
该应用程序崩溃。基本上,我正在尝试使用任意数量的径向角实现QML Button,例如,右下角是径向角,其他角是垂直的:
或左下角呈放射状转角,其他角垂直:
上角相同。
答案 0 :(得分:0)
您不能像这样在QML中嵌入Qt小部件。 QML使用场景图(可以将QGraphicsProxyWidget
与使用QGraphicsView
的Qt Quick 1一起使用。
现在您必须使用QQuickPaintedItem
。
但是,通过使用Shape
,在QML中直接制作带有径向角的按钮非常容易。
一个简单的例子:
Button {
id: button
background: Shape {
ShapePath {
id: shape
property int angleRadius: 12
strokeWidth: 4
fillColor: "red"
startX: 0; startY: 0
PathLine { x: button.width; y: 0 }
PathLine { x: button.width; y: button.height - shape.angleRadius }
PathArc {
x: button.width - shape.angleRadius; y: button.height
radiusX: shape.angleRadius
radiusY: shape.angleRadius
}
PathLine { x: 0; y: button.height }
PathLine { x: 0; y: 0 }
}
}
text: "Confirm"
}
如果您不想使用Shape
,则可以使用基本的Rectangle
(无边框):其中一个带有圆角,另外两个带有圆角。
例如:
Button {
id: button2
background: Rectangle {
id: bg
radius: 8
color: "green"
Rectangle {
width: bg.width
height: bg.radius
x: 0
y: 0
color: bg.color
}
Rectangle {
width: bg.radius
height: bg.height
x: 0
y: 0
color: bg.color
}
}
text: "Confirm"
}
如果您真的想使用C ++类,请使用QQuickPaintedItem
:
class Button : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor)
Q_PROPERTY(QString text READ text WRITE setText)
public:
Button(QQuickItem* parent=nullptr): QQuickPaintedItem(parent) {
setAcceptedMouseButtons(Qt::LeftButton);
}
virtual void paint(QPainter* painter) override
{
QPainterPath path;
path.setFillRule(Qt::WindingFill);
path.addRoundRect(contentsBoundingRect(), 90, 90);
path.addRect(0, 0, width(), height() / 2);
path.addRect(0, 0, width() / 2, height());
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(color());
painter->drawPath(path);
painter->restore();
}
QColor color() const { return bgColor; }
QString text() const { return contentText; }
public slots:
void setColor(QColor const& color) { bgColor = color; }
void setText(QString const& text) { contentText = text; }
signals:
void clicked();
private:
QColor bgColor;
QString contentText;
QElapsedTimer pressedTimer;
virtual void mousePressEvent(QMouseEvent* event) override
{
if (event->button() != Qt::MouseButton::LeftButton)
{
pressedTimer.invalidate();
return;
}
pressedTimer.restart();
}
virtual void mouseReleaseEvent(QMouseEvent* /*event*/) override
{
if (pressedTimer.elapsed() < 200)
clicked();
pressedTimer.invalidate();
}
};
// In main.cpp
qmlRegisterType<Button>("my.app", 1, 0, "MyButton");
// main.qml
MyButton {
text: "Cancel"
color: "blue"
width: 60
height: 30
onClicked: console.log("Clicked")
}