What JS objects are available in Qt Creator JS: variable expansion? - qt

Qt Creator's wizards and configuration settings supports variable expansion, including evaluation of JavaScript expressions, e.g. the C++ class wizard file template contains:
%{JS: Cpp.openNamespaces('%{Class}')}
Cpp seems to be a global object. Where in the Qt Creator sources are those defined, and what's available?
These are not documented anywhere.

The JavaScript variable expansion is performed by the JsExpander in the core plugin. The expander can register QObject instances and expose them as properties of the global JS object.
To find all of those global objects, search for registerQObjectForJs method invocations. See the github search results for this method.
As of Qt Creator 4.2.1, and until at least 4.6, the following are the only objects registered:
Util - exposing Internal::UtilsJsExtension,
Cpp - exposing CppTools::Internal::CppToolsJsExtension,
Modeling - exposing ModelEditor::Internal::JsExtension,
QtSupport - exposing QtSupport::CodeGenerator,
Vcs - exposing VcsBase::Internal::VcsJsExtension.
The method parameter types are mapped to JavaScript types by QJSEngine. E.g. to obtain the Qt includes, one could have the following substitution:
%{JS: QtSupport.qtIncludes([ '%{Base}' ], [ '%{Base}' ])}
given the signature
QString qtIncludes(const QStringList &qt4, const QStringList &qt5)
The method list follows.
Util
QString toNativeSeparators(const QString &in) const;
QString fromNativeSeparators(const QString &in) const;
QString baseName(const QString &in) const;
QString fileName(const QString &in) const;
QString completeBaseName(const QString &in) const;
QString suffix(const QString &in) const;
QString completeSuffix(const QString &in) const;
QString path(const QString &in) const;
QString absoluteFilePath(const QString &in) const;
QString relativeFilePath(const QString &path, const QString &base) const;
// File checks:
bool exists(const QString &in) const;
bool isDirectory(const QString &in) const;
bool isFile(const QString &in) const;
// MimeDB:
QString preferredSuffix(const QString &mimetype) const;
// Generate filename:
QString fileName(const QString &path,
const QString &extension) const;
// Generate temporary file:
QString mktemp(const QString &pattern) const;
// Generate a ascii-only string:
QString asciify(const QString &input) const;
Cpp
// Generate header guard:
QString headerGuard(const QString &in) const;
// Fix the filename casing as configured in C++/File Naming:
QString fileName(const QString &path, const QString &extension) const;
// Work with classes:
QStringList namespaces(const QString &klass) const;
QString className(const QString &klass) const;
QString classToFileName(const QString &klass,
const QString &extension) const;
QString classToHeaderGuard(const QString &klass, const QString &extension) const;
QString openNamespaces(const QString &klass) const;
QString closeNamespaces(const QString &klass) const;
Modeling
QString fileNameToElementName(const QString &file);
QString elementNameToFileName(const QString &element);
QtSupport
// Ui file related:
// Change the class name in a UI XML form
QString changeUiClassName(const QString &uiXml, const QString &newUiClassName);
QString uiClassName(const QString &uiXml);
// Generic Qt:
QString qtIncludes(const QStringList &qt4, const QStringList &qt5);
Vcs
bool isConfigured(const QString &vcsId) const;
QString displayName(const QString &vcsId) const;

It is also useful to note that several JS variables exposed via the macroexpander see:
https://github.com/qt-creator/qt-creator/blob/master/src/plugins/coreplugin/coreplugin.cpp#L169

Related

Alternatives to QProcess::startDetached() and QProcess start() as they are deprecated

What are the alternatives to QProcess::startDetached() and QProcess::start() to start an external application as they are marked deprecated in qt5?
Only some overloads of the start() and startDetached() method are deprecated like:
void start(const QString &command, QIODevice::OpenMode mode = ReadWrite)
bool startDetached(const QString &command)
But the others are still available:
void QProcess::start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite)
void QProcess::start(QIODevice::OpenMode mode = ReadWrite)
bool QProcess::startDetached(qint64 *pid = nullptr)
bool QProcess::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(), qint64 *pid = nullptr)

Resizing a QTableView column horizontally to the content of an item delegated column which is painted with a new text in Qt

I want to show my database tabel content in a QTableView. I use the following codes to do that:
QSqlDatabase test = QSqlDatabase::addDatabase("QMYSQL");
test.setDatabaseName("dbText");
test.setHostName("localhost");
test.setUserName("***");
test.setPassword("***");
if (!test.open())
qDebug()<<"ERROR ";
QSqlTableModel *model = new QSqlTableModel(this,test);
model->setTable("textTable");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->tableView->setModel(model);
ui->tableView->show();
As it is depicted in the following picture, ui->tableView columns are resized to the content of the database table columns.
Now, I want to clear the display text of Description column and paint it with new text and color. For this propose, I have used the function QTableView::setItemDelegateForColumn as follow:
ui->tableView->setItemDelegateForColumn(2,new PowerColorDelegate(this));
And here are PowerColorDelegate header and source file content:
PowerColorDelegate.h
#include <QStyledItemDelegate>
class PowerColorDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
PowerColorDelegate(QObject *parent = 0);
protected:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QString displayText(const QVariant &value, const QLocale &locale) const;
};
PowerColorDelegate.cpp
#include <QApplication>
#include <QPainter>
#include "powercolordelegate.h"
PowerColorDelegate::PowerColorDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
}
void PowerColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
if(!index.isValid())
{
QStyledItemDelegate::paint(painter, option, index);
return;
}
// Position our pixmap
const int x = option.rect.left();
const int y = option.rect.top();
QString newColor = "#fcaf9e";
QString newText = "This is my new text which I want to paint!";
painter->fillRect(option.rect, newColor);
painter->drawText(QRect(x, y, 80, 20), newText);
QStyledItemDelegate::paint(painter, opt, index);
}
QString PowerColorDelegate::displayText(const QVariant &value, const QLocale &locale) const
{
return "";
}
The result of using PowerColorDelegate on ui->tableView is shown in this picture:
How can I resize the third ui->tableView column (Description) horizontally to the content of the painted column?
Implement sizeHint for your delegate according to required text format

QListView moveRow() from model not called

I'm having a Listview which should show a preview of an image. For this I created a the item "ListItem"
class ListItem
{
public:
ListItem();
ListItem(QString name, QImage image);
QImage* previewIcon();
void setPreviewIcon(QImage icon);
QImage *image();
void setImage(QImage* image);
void setImage(QImage image);
void setName(QString name);
void setChecked(bool checked);
QString name();
bool checked();
private:
QImage m_preview;
QImage m_image;
QString m_name;
bool m_checked;
};
This model stores the image it self and a preview of it. This works fine for inserting and removing items:
class ListModel: public QAbstractListModel
{
Q_OBJECT
public:
ListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;
bool removeRow(int row, const QModelIndex &parent = QModelIndex());
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
bool insertRow(int row, const QModelIndex &parent = QModelIndex());
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
bool appendItem(ListItem* item);
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
bool moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild);
Qt::DropActions supportedDropActions() const override;
QHash<int, QByteArray> roleNames() const override;
private:
ListItem* getItem(const QModelIndex &index) const;
private:
QList<ListItem*> m_scannedDocuments;
};
This is the setup of the QListView:
m_scannedDocumentsModel = new ListModel();
m_scannedDocuments = new QListView();
m_scannedDocuments->setModel(m_scannedDocumentsModel);
m_scannedDocuments->setDragDropMode(QAbstractItemView::InternalMove);
m_scannedDocuments->setMovement(QListView::Snap);
m_scannedDocuments->setDefaultDropAction(Qt::MoveAction);
Dragging and droping is fine for the preview, the name and if it is checked or not. The problem is the image "m_image". When I'm doing a move in the view, the view calls insertRows() and inserts a new item and removes the old item, but does not call moveRows.
Why moveRows() is not called?
Here you can find the full implementation:
ListModel.cpp
ListModel.h
Another approach would be to create a userRole for the image it self. Here I tried to reimplement roleNames() as
QHash<int, QByteArray> ListModel::roleNames() const {
QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
roles[Qt::UserRole] = "Qt::UserRole";
return roles;
}
and check the roles in setdata()/data() but this didn't work either.
What is the best way to have a complex model and moving them in a listview?
As already answered in brief on the Qt interest list:
Because moveRows was added in Qt 5.x, and drag and drop in Qt 4, and still uses insert+remove for backwards compatibility.
I'd add that "moveRows" is I guess considered an "optimization" and not really a requirement for a model, and the view has no way to know if the move methods are really implemented. Since an editable model requires remove/insert functions, it's "safer" to call those by default.
You can re-implement the model's dropMimeData() method and call moveRows() yourself. But, the caveat is you should return false from the method if you do this. If you return true to a Qt::MoveAction, the view will still try to remove the row from the old position in the model (which is obviously not what you want).

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.

QTableWidget with automatic restore of old cell value

I'm just getting started with QT, so please exercise a little patience...
I've an editable QTableWidget (actually a subclassing), and need to implement the following behavior.
When the user types a non acceptable value I would like:
1) to restore the original value;
2) to keep the focus in the cell and set it in edit mode.
I'm currently using the itemChanged SIGNAL, and a subclassing of QTableWidgetItem.
Which one is the best way to get what I need?
Any tip, suggestion or reference is really welcome.
If you think it as useful I can post some code.
Ciao
Alf.
I'm currently using the itemChanged SIGNAL...
You should subclass QStyledItemDelegate
class CustomTableDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
CustomTableDelegate (QObject * parent = 0);
QWidget * createEditor (QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const;
bool editorEvent (QEvent *, QAbstractItemModel *, const QStyleOptionViewItem &, const QModelIndex &);
void setEditorData (QWidget *, const QModelIndex &) const;
void setModelData (QWidget *, QAbstractItemModel *, const QModelIndex &) const;
};
And implement validation inside setModelData.
To use custom delegate you need set it for your QTableWidget:
table->setItemDelegate (new CustomTableDelegate () );

Resources