i need help about implementing a code to Swaps the nodes at the index with the node prior to it - list

template
class Node {
public:
Node(const T& data); //Node Constructor
T& GetData(); //Node Data Getter
void SetData(const T& data); //Node Data Setter
Node* GetNext(); //Node m_next getter
void SetNext(Node* next); //Node m_next setter
private:
T m_data; //Holds templated data
Node* m_next; //Pointer to next node
};
void Swap(int);
private:
Node *m_head; //Node pointer for the head
Node *m_tail; //Node pointer for the tail
int m_size; //Number of nodes in queue

Related

Using Custom data type in QT TreeModel

This is my Container class defination
class Container
{
private:
std::string stdstrContainerName;
std::string stdstrPluginType;
std::string stdstrPluginName;
int iSegments;
float fRadius;
public:
Container();
explicit Container(std::string strContainerName , std::string
strPluginName , std::string strPluginType, int segments , float
radius );
~Container();
std::string GetName();
std::string GetType();
void SetName(std::string stdstrName);
};
I want the nodes of the TreeView to hold object of Container class as data.
This is the header file for the TreeItem class.
class TreeItem
{
public:
explicit TreeItem( const Container &data , TreeItem *parent = 0 );
~TreeItem();
TreeItem *parent();
TreeItem *child(int iNumber);
int childCount() const;
int childNumber() const;
Container data() const;
bool setData(const Container &data);
bool insertChildren(int position, int count );
bool removeChildren( int position , int count );
private:
QList<TreeItem*> childItems;
Container itemData;
TreeItem* parentItem;
};
The problem i am facing is while implementing the TreeModel functions.
how can i use Container as the data type instead of QVariant.
QVariant data(const QModelIndex &undex, int role) const override;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
bool setData( const QModelIndex &index , const QVariant &value , int
role = Qt::EditRole) override;
You can't use Container instead of QVariant, but you can use Container inside a QVariant. Have a look at Q_DECLARE_METATYPE.
Add it in the header file after the declaration of Container:
class Container
{
private:
// ...
public:
Container();
// ...
};
Q_DECLARE_METATYPE(Container); // You only need this once, so here is a good place
When you created the Container meta type, you can return it like this:
QVariant data(const QModelIndex &index, int role) const override {
TreeItem *item = ...;
return QVariant::fromValue(item->data());
}
And in your view you retrieve the Container like this:
QVariant v = model()->data(index, role);
Container c = v.value<Container>();
Beware that this only works within the same thread, else you'd need to register Container with qRegisterMetaType() and maybe even write a converter function from / to QVariant.
This doesn't apply to your situation, though, because model and view are not designed to live in different threads.

QML : reload a model

I have a model I'm using in a Combobox. The model is well loaded at start. But I would like to reload it. I tried to use Q_INVOKABLE, but it doesn't work.
My model is defined in a header :
class StrategiesModel : public QAbstractListModel
{
Q_OBJECT
public:
enum StrategiesRoles{
textRole =Qt::UserRole + 1
};
explicit StrategiesModel(QObject *parent = nullptr);
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE bool loadStrategie();
private:
QStringList mStrategies;
const QString mFileName = "listStrategies.txt";
};
and in the source :
#include "strategiesmodel.h"
StrategiesModel::StrategiesModel(QObject *parent)
: QAbstractListModel(parent)
{
loadStrategie();
}
int StrategiesModel::rowCount(const QModelIndex &parent) const
{
// For list models only the root node (an invalid parent) should return the list's size. For all
// other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
if (parent.isValid())
return 0;
// FIXME: Implement me!
return mStrategies.size();
}
QVariant StrategiesModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
// FIXME: Implement me!
if(role == textRole)
return QVariant(mStrategies[index.row()]);
else
return QVariant();
}
QHash<int, QByteArray> StrategiesModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[textRole] = "text";
return roles;
}
bool StrategiesModel::loadStrategie()
{
mStrategies.clear();
// Loading list from a file
}
In the main, the model is load like this:
qmlRegisterType<StrategiesModel>("Strategies", 1, 0, "StrategiesModel");
But when I tried to reload the model, it fails:
strategies.model: StrategiesModel {} // First load works
strategies.textRole: "text"
refresh.onClicked: function(){
StrategiesModel.loadStrategie(); // Fail
}
I got this error :
TypeError: Property 'loadStrategie' of object [object Object] is not a function
How can I made my function accessible?
Thanks in adavance!
When you use the name of the class you are not accessing an object so you can not use any method, what you can do is use the existent object through its id:
strategies.model: StrategiesModel{ id: some_model} // First load works
strategies.textRole: "text"
refresh.onClicked: function(){
some_model.loadStrategie();
}
According to what I check the loadStrategie loads new data to the model, so that the view is notified you must use beginResetModel() before the change and endResetModel() after making the changes.
*.cpp
bool StrategiesModel::loadStrategie()
{
beginResetModel();
mStrategies.clear();
...
// Loading list from a file
...
endResetModel();
}

QT signal error: “this” is unavailable for static member function

I'm working at a socket class for my application that will introduce me in QT framework. When I try to build I get this error: 'this' is unavailable for static member functions.
This is my class .h and .cpp
#pragma once
#include <QObject>
class QTcpSocket;
namespace Ps{
class InstSocket : public QObject
{
Q_OBJECT
public:
InstSocket(QObject *parent=0);
bool Connect();
bool isOpen();
void Disconnect();
//Geters
QString GetHostName() const {return m_hostName;}
quint16 GetPort() const {return m_port;}
//seters
void SetHostName(const QString& value);
void SetPort(quint16 value);
void SetLongWaitMs(int value){m_longWaitMs = value;}
void SetShortWaitMs(int value){m_shortWaitMs = value;}
void WriteData(const QString &data) const;
~InstSocket();
QString ReadData() const;
signals:
static void NotifyConnected();
static void NotifyDisconnected();
private slots:
void onConnected();
void onDisconnected();
private:
//this holds a reference to QtcpSocket
QTcpSocket& m_socket;
QString m_hostName;
quint16 m_port;
int m_shortWaitMs;
int m_longWaitMs;
explicit InstSocket(const InstSocket& rhs) = delete;
InstSocket& operator= (const InstSocket& rhs) = delete;
};
}
and the cpp:
#include "instsocket.h"
#include "QTcpSocket"
#include "QDebug"
#include "utils.h"
namespace Ps
{
InstSocket::InstSocket(QObject *parent) :
QObject(parent),
m_socket(*new QTcpSocket(this)),
m_hostName(""),
m_port(0),
m_shortWaitMs(0),
m_longWaitMs(0)
{
/* my signals are wired to the undelying socket signals, the signal connected is triggered, when a conection
* is established. This will be wired to onConnected and Disconnected slots*/
connect(&m_socket, &QTcpSocket::connected, this, &InstSocket::onConnected);
connect(&m_socket, &QTcpSocket::disconnected, this, &InstSocket::onDisconnected);
}
bool InstSocket::Connect()
{
qDebug() << "attempting to connect to "<< m_hostName << "on port" << m_port << "with wait time: "<<m_longWaitMs;
m_socket.connectToHost(m_hostName, m_port, QTcpSocket::ReadWrite);
return m_socket.waitForConnected(m_longWaitMs);
}
bool InstSocket::isOpen()
{
return m_socket.isOpen();
}
void InstSocket::Disconnect()
{
if(!isOpen()) return;
m_socket.disconnectFromHost();
}
void InstSocket::onConnected()
{
emit NotifyConnected();
}
void InstSocket::onDisconnected()
{
emit NotifyDisconnected();
}
void InstSocket::SetHostName(const QString &value)
{
m_hostName = value;
}
void InstSocket::SetPort(quint16 value)
{
m_port = value;
}
void InstSocket::WriteData(const QString &data) const
{
/*support for writeing to socket. The write metod of the socket will return the number of bites writen*/
int bytes_written = m_socket.write(qPrintable(data));
qDebug() << "Bytes written: "<<bytes_written;
}
QString InstSocket::ReadData() const
{
if(!m_socket.isReadable())
{
return "ERROR: Socket is unreadable.";
}
QString result;
//until the socket reports there is no data available
while(!m_socket.atEnd())
{
result.append(m_socket.readAll());
/*since typically a PC would be much faster at reading than an instrument might be at writing
* instrument must have a chance to queue up more data in case the message it's sending us is long.*/
m_socket.waitForReadyRead(m_shortWaitMs);
}
return result;
}
InstSocket::~InstSocket()
{
Utils::DestructorMsg(this);
}
}
and this is the error:
Qt Projects\build-Vfp-Desktop_Qt_5_7_0_MSVC2015_64bit-Debug\debug\moc_instsocket.cpp:-1: In static member function 'static void Ps::InstSocket::NotifyConnected()':
error: 'this' is unavailable for static member functions
QMetaObject::activate(this, &staticMetaObject, 0, Q_NULLPTR); In static member function 'static void Ps::InstSocket::NotifyDisconnected()':
error: 'this' is unavailable for static member functions
QMetaObject::activate(this, &staticMetaObject, 1, Q_NULLPTR);
When I clicked on them, QT creator took me to moc_instsocket.cpp (that is in build folder and poit to this:
// SIGNAL 0
void Ps::InstSocket::NotifyConnected()
{
QMetaObject::activate(this, &staticMetaObject, 0, Q_NULLPTR);
}
// SIGNAL 1
void Ps::InstSocket::NotifyDisconnected()
{
QMetaObject::activate(this, &staticMetaObject, 1, Q_NULLPTR);
}
I can't figure out what to do althought I checked all the code several times. There is no need to know about utils class since there are just some debug messages. Did anyone know how to fix it?
What is the meaning of static signal? In Qt signals and slots are used on object level.
signals:
static void NotifyConnected();
static void NotifyDisconnected();
All classes that inherit from QObject or one of its subclasses (e.g., QWidget) can contain signals and slots. Signals are emitted by objects when they change their state in a way that may be interesting to other objects. This is all the object does to communicate. It does not know or care whether anything is receiving the signals it emits. This is true information encapsulation, and ensures that the object can be used as a software component. Signal Slots documentation

add rows in the List

I have class called List to print a list
class List : public QAbstractListModel
{
Q_OBJECT
Q_ENUMS(Roles)
public:
enum Roles {
address = Qt::UserRole + 1,
name
};
DeviceList(QObject *parent = 0);
void addrows(const Manager &client);
int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
protected:
QHash<int, QByteArray> roleNames() const;
private:
QList< Manager > m_client;
};
And another class Manager as
class Manager : public QObject
{
Q_OBJECT
Q_PROPERTY(List* List READ getList CONSTANT)
public:
Manager(const QString &address, const QString &name);
QString address() const;
QString name() const;
virtual List* getList() = 0;
private:
QString m_address;
QString m_name;
};
Now i am trying to addrows in manager.cpp as
void List::addrows(const Manager &client)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_client << client; // **i am getting error here**
endInsertRows();
}
My intention is to implement getlist in manager.cpp file
List* Manager :: getList()
{
List* list = new List();
list->addrows(Manager("street1","John"));
list->addrows(Manager("street2:","Tim"));
list->addrows(Manager("street3","Roberrt"));
return list;
}
In order to use the operator << you have to override the operator = in the class Manager. Instead of doing that use List and handle list elements as pointer.

How to access Items stored in a QAbstractListmodel in QML(by delegates) otherwise than using item roles?

I just want to display elements from list using QML, but not using item roles.
For ex. I want to call a method getName() that returns the name of the item to be displayed.
Is it possible? I didn't find nothing clear reffering to this.
You can use one special role to return the whole item as you can see below:
template<typename T>
class List : public QAbstractListModel
{
public:
explicit List(const QString &itemRoleName, QObject *parent = 0)
: QAbstractListModel(parent)
{
QHash<int, QByteArray> roles;
roles[Qt::UserRole] = QByteArray(itemRoleName.toAscii());
setRoleNames(roles);
}
void insert(int where, T *item) {
Q_ASSERT(item);
if (!item) return;
// This is very important to prevent items to be garbage collected in JS!!!
QDeclarativeEngine::setObjectOwnership(item, QDeclarativeEngine::CppOwnership);
item->setParent(this);
beginInsertRows(QModelIndex(), where, where);
items_.insert(where, item);
endInsertRows();
}
public: // QAbstractItemModel
int rowCount(const QModelIndex &parent = QModelIndex()) const {
Q_UNUSED(parent);
return items_.count();
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
if (index.row() < 0 || index.row() >= items_.count()) {
return QVariant();
}
if (Qt::UserRole == role) {
QObject *item = items_[index.row()];
return QVariant::fromValue(item);
}
return QVariant();
}
protected:
QList<T*> items_;
};
Do not forget to use QDeclarativeEngine::setObjectOwnership in all your insert methods. Otherwise all your objects returned from data method will be garbage collected on QML side.

Resources