30 июня 2010

Калькулятор в каждый QLineEdit? Легко.

Attention: Qt Script with bindings used.
Итак задача: пользователь вводит какой-либо результат в QLineEdit списывая его из какого-нибудь листочка. Однако если на листочке есть только исходные данные, но не вычислен результат? Поэтому мною был придуман виджет калькулятор, который работает с QLineEdit'ом имеющим фокус ввода. Пользователь вводит исходное выражение, а виджет вычисляет результат. Итак модифицированный код из прошлого сообщения моего блога:

29 июня 2010

Объект String в Qt Script и номер unicode символа

String.fromCharCode
СинтаксисString.fromCharCode(num1, ..., numN)

Аргументы
num1, ..., numN
последовательность чисел, представляющих собой коды Unicode-символов
Описание, примеры

Этот метод возвращает элементарную строку, а не объект типа String.

Так как fromCharCode - статический метод String, он всегда вызывается как String.fromCharCode().

Ссылка на первоисточник
Данная функция присутствует и в Qt Script. Пример использования:

String.fromCharCode(QLocale.system().decimalPoint())

Простая цифровая экранная клавиатура на Qt Script

Создание такой клавиатуры не составляет труда. Но я ее сделал на Qt Script в сочетании с Qt Script Bindings Generator. Я не правильно выражаюсь, вот как надо понимать словосочетание Qt Script Bindings Generator: "Qt Script плагины, осуществляющие доступ к почти все объектам Qt".

27 июня 2010

Добавляем QListView на QMenu

Добавляем с помощью спецаильно обученного класса QWidgetAction. QListView будет отображаться только на одном меню, куда он был впервые установлен.
QMenu *menu = new QMenu(0);
listView = new QListView(0);
QWidgetAction *wA;
wA = new QWidgetAction(this);
wA->setDefaultWidget(listView);
menu->addAction(wA);

26 июня 2010

Как "динамически" соединить сигнал с сигналом/слотом?

Обычно соединение происходит в виде: connect(obj1, SIGNAL(signal()), obj2, SLOT(slot())); Но такой код не сработает, если имя слота хранится в переменной. Для решения проблемы имитируем макросы SIGNAL и SLOT.

QString signal1 = QMetaObject::normalizedSignature("signal1( )");
QString signal2 = QMetaObject::normalizedSignature("signal2( )");
QString slot1 = QMetaObject::normalizedSignature("slot( )");
connect(obj1, QString("%1%2").arg(QSIGNAL_CODE).arg(signal1).toLatin1().data()
, obj2, QString("%1%2").arg(QSIGNAL_CODE).arg(signal2).toLatin1().data());
connect(obj1, QString("%1%2").arg(QSIGNAL_CODE).arg(signal2).toLatin1().data()
, obj3, QString("%1%2").arg(QSLOT_CODE).arg(slot1).toLatin1().data());

Стандартный делегат с возможностью дополнения.

Наследуемся от QStyledItemDelegate.
Заголовочный файл pgqueryitemdelegate.h
class PGQueryItemDelegate : public QStyledItemDelegate
{
  Q_OBJECT
  public:
  explicit PGQueryItemDelegate(QObject* parent = 0);

  QWidget* createEditor (QWidget* parent,
                         const QStyleOptionViewItem& option,
                         const QModelIndex& index ) const;

protected:
  virtual bool eventFilter(QObject *object, QEvent *event);
};
Файл реализации pgqueryitemdelegate.cpp
PGQueryItemDelegate::PGQueryItemDelegate(QObject* parent):QStyledItemDelegate(parent)
{
  setObjectName("pgQueryItemdelegate");
}

QWidget *PGQueryItemDelegate::createEditor(QWidget *parent,
                                           const QStyleOptionViewItem &option,
                                           const QModelIndex & index ) const
{
  QWidget *editor = QStyledItemDelegate::createEditor(parent, option, index);
  QLineEdit* lineEdit = qobject_cast(editor);
  if (lineEdit) {
    QMap<QString, int> values;
    QString itemData;
    int start = qMax(0, index.row() - 600);
    int end = qMin(index.model()->rowCount(index.parent()), index.row() + 600);
    for (int row = start; row < end; ++row) {
      itemData = index.model()->index(row, index.column(), index.parent()).data().toString();
      values.insert(itemData, index.row());
    }

    QCompleter* completer = new QCompleter(values.keys(), lineEdit);
    completer->setCompletionColumn(0);
    completer->setModelSorting(QCompleter::CaseSensitivelySortedModel);
    completer->setCompletionMode(QCompleter::InlineCompletion);
    lineEdit->setCompleter(completer);
    return lineEdit;
  }

  return editor;
}

bool PGQueryItemDelegate::eventFilter(QObject *object, QEvent *event)
{
  if (event->type() == QEvent::FocusIn) {
    QLineEdit *lineEdit = qobject_cast(object);
    if (lineEdit) {
      if (lineEdit->completer())
        lineEdit->completer()->setCompletionMode(QCompleter::PopupCompletion);
    }
  }
  if (event->type() == QEvent::FocusOut) {
    QLineEdit *lineEdit = qobject_cast(object);
    if (lineEdit) {
      QFocusEvent *focusEvent = static_cast(event);
      if (lineEdit->completer())
        if (qApp->activeWindow() == lineEdit->completer()->popup())
          return true;
    }
  }
  return QStyledItemDelegate::eventFilter(object, event);
}

Получить комментарий к pgsql объектам "по-быструхе"

Attention: используется Qt Script. 
Механизм комментариев в postgresql представляет собой очень такой упругий клапан: комментарий задать легче простого, получить его обратно "почти невозможно". Официальная postgres документация, рассказывает о 4 функциях. google.com на запрос "postgresql get object comment" отсылает к оф. документации.
Если у кого есть отточенный механизм, то он скорее всего выужен из исходного кода psql или pgAdmin. Мне туда лезть пока не хочеться, хватает дебрей Qt.

Итак отобрать обратно комментарий от собственно самой базы данных, к которой мы сейчас подключены:
var query = new QSqlQuery(database);
query.exec("select description from pg_shdescription join pg_database on objoid = oid and datname = current_database()");
query.next();
print(query.value(0));

Получить комментарий к таблице:
var tableName = "tableName";
var sqlQuery = new QSqlQuery(database);
sqlQuery.exec("select description from pg_description where objsubid = 0 and objoid = '%1'::regclass ".arg(tableName));
query.next();
print(sqlQuery.value(0));

Получить комментарий к столбцу:
var columnIndex = 1;
var tableName = "tableName";
var sqlQuery = new QSqlQuery(database);
sqlQuery.exec("select description from pg_description where objsubid = %2 and objoid = '%1'::regclass ".arg(tableName).arg(columnIndex));
query.next();
print(sqlQuery.value(0));

18 июня 2010