Имеется графический элемент QML основанный на классе QQuickPaintedItem
invitemslot.h
#ifndef INVITEMSLOT_H
#define INVITEMSLOT_H
#include<QtQuick/QQuickPaintedItem>
#include <QColor>
#include <QBrush>
#include <QPen>
#include <QPainter>
#include <QImage>
#include <QStaticText>
#include <InvItem>
#include <QMouseEvent>
#include <QAbstractButton>
#include <QtQuickWidgets/QQuickWidget>
class InvItemSlot : public QQuickPaintedItem
{
public:
explicit InvItemSlot(QQuickItem *parent = 0);
Q_OBJECT
Q_PROPERTY(int slotIndex READ slotIndex WRITE setSlotIndex NOTIFY slotIndexChanged)
Q_PROPERTY(QColor background READ background WRITE setBackground NOTIFY backgroundChanged)
Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged)
Q_PROPERTY(QString slotState READ slotState WRITE setSlotState NOTIFY slotStateChanged)
Q_PROPERTY(InvItem* containedItem READ containedItem WRITE setContainedItem NOTIFY containedItemChanged)
// Q_PROPERTY(InvItem containedItem READ containedItem)
int slotIndex();
QColor background();
QColor borderColor();
QString slotState();
InvItem *containedItem();
Q_INVOKABLE void setIcon(QString url);
void paint(QPainter *painter) override;
public slots:
void setSlotIndex(int slotIndex);
void setBackground(QColor background);
void setBorderColor(QColor borderColor);
void setSlotState(QString slotState);
void setContainedItem(InvItem *containedItem);
void setIcon();
signals:
void slotIndexChanged(int slotIndex);
void backgroundChanged(QColor background);
void borderColorChanged(QColor borderColor);
void slotStateChanged(QString slotState);
void containedItemChanged(InvItem *containedItem);
private:
int m_slotIndex;
QColor m_background;
QColor m_borderColor;
QString m_slotState;
InvItem *m_containedItem = new InvItem(this);
QImage icon;
};
#endif // INVITEMSLOT_H
invitemslot.cpp
#include "invitemslot.h"
#ifdef DEBUG
#include <QDebug>
#endif
InvItemSlot::InvItemSlot(QQuickItem *parent) :
QQuickPaintedItem(parent),
m_background(35, 35, 35,102),
m_borderColor(Qt::white)
{
connect(m_containedItem, SIGNAL(itemPropertiesChanged(QVariant)), this, SLOT(setIcon()));
}
void InvItemSlot::paint(QPainter *painter){
QBrush brush(m_background);
QPen border;
QPen textPen(Qt::red);
textPen.setWidth(20);
border.setWidth(5);
if(m_slotState == "pressed"){
m_background = QColor(102,102,102,102);
m_borderColor = QColor(102,102,102,102);
}else if(m_slotState == "released"){
m_background = QColor(35, 35, 35,102);
m_borderColor = QColor(Qt::white);
}else if (m_slotState == "selected") {
m_background = QColor(35, 35, 35,102);
m_borderColor = QColor(Qt::red);
}
border.setColor(m_borderColor);
painter->setRenderHints(QPainter::Antialiasing, true);
painter->setRenderHints(QPainter::SmoothPixmapTransform, true);
painter->setRenderHints(QPainter::HighQualityAntialiasing, true);
painter->setPen(border);
painter->setBrush(brush);
painter->drawRect(QRectF(0,0,this->width(),this->height()));
painter->drawImage(QRectF(5,5,(this->width() - (border.width()*2)),(this->height() - (border.width()*2))),icon);
QStaticText itemName(m_containedItem->itemName());
painter->setPen(Qt::NoPen);
painter->setBrush(QBrush(Qt::black));
painter->drawRect(QRectF(0,0,itemName.textWidth(),20));
painter->drawStaticText(QPointF(0,0),itemName);
if(m_slotState == "pressed"){
painter->setPen(textPen);
painter->drawText(QRectF(0,0,this->width(),this->height()),Qt::AlignCenter,m_containedItem->itemName());
}
}
int InvItemSlot::slotIndex(){return m_slotIndex;}
void InvItemSlot::setSlotIndex(int slotIndex){
m_slotIndex = slotIndex;
emit slotIndexChanged(slotIndex);
return;
}
QColor InvItemSlot::background(){return m_background;}
void InvItemSlot::setBackground(QColor background){
m_background = background;
emit backgroundChanged(background);
return;
}
QColor InvItemSlot::borderColor(){return m_borderColor;}
void InvItemSlot::setBorderColor(QColor borderColor){
m_borderColor = borderColor;
emit borderColorChanged(borderColor);
return;
}
QString InvItemSlot::slotState(){return m_slotState;}
void InvItemSlot::setSlotState(QString slotState){
bool blocked = false;
if(slotState == "pressed"){
m_slotState = slotState;
}else if (slotState == "released") {
m_slotState = slotState;
}else if (slotState == "selected") {
m_slotState = slotState;
}else{
blocked = true;
}
update();
emit slotStateChanged(slotState);
}
InvItem *InvItemSlot::containedItem(){
return m_containedItem;
}
void InvItemSlot::setContainedItem(InvItem *overrideItem){
disconnect(m_containedItem, SIGNAL(itemPropertiesChanged(QVariant)), this, SLOT(setIcon()));
m_containedItem = overrideItem;
connect(m_containedItem, SIGNAL(itemPropertiesChanged(QVariant)), this, SLOT(setIcon()));
emit containedItemChanged(m_containedItem);
}
void InvItemSlot::setIcon(){
QString url = m_containedItem->itemProperties().toJsonObject().value("iconSorce").toString();
qDebug()<<"Load:"<<url;
icon.load(url);
update();
}
void InvItemSlot::setIcon(QString url){
icon.load(url);
update();
}
//void InvItemSlot::mousePressEvent(QMouseEvent *event){
// if(event->button() == Qt::LeftButton){
// }
//}
Хочется сделать элемент кликабельным, чтобы не писать в QML костыли вроде такого:
main.qml
InvItemSlot{
width: 100;
height: 100;
MouseArea{
anchors.fill: parent;
onPressed: slotState = "pressed";
onReleased: slotState = "released";
}
}
Попытался использовать QAbstractButton, но не получается ввиду того, что класс QQuickPaintedItem унаследован от QQuickItem, в то время как класс QAbstractButton от QWidget, попытка прописать наследования постоянноутыкается в следующие ошибки:
C:\Users\User\Documents\QtProjects\MainDot\gameAPI\invitemslot.h:60: error: 'QObject' is an ambiguous base of 'InvItemSlot'
InvItem *m_containedItem = new InvItem(this);
^
C:\Qt\5.9.1\mingw53_32\include\QtCore\qmetatype.h:1376: error: 'QObject' is an ambiguous base of 'InvItemSlot'
enum { Value = sizeof(checkType(static_cast<T*>(Q_NULLPTR))) == sizeof(yes_type) };
^