Записки программиста Программирование и не только

19Апр/123

МСВС и Qt

Понадобилось запустить программу под МСВС3.0 (Kernel 2.4.32, gcc-2.95 и 3.3, Qt 4.4.2)
Сама программа писалась под Qt 4.6.3
Отличия 4.6 от 4.4 достаточно существенны, чтобы программы не компилировалась совсем.
Статическая сборка (собиралось под gcc44 и на ядре 2.6+) работать отказалась, мотивируя отказ фразой "Исключение в операции с плавающей точкой (core dumped)"

Решил задачу так.
Qt 4.6 можно собрать только на gcc4, поэтому скачал gcc-4.2, скомпилировал и поставил.
Скачал qt-4.6.3 (qt-everywhere-opensource-src-4.6.3.tar.gz), распаковал, собрал как статику:
./configure -debug-and-release -static -qt-sql-sqlite -no-qt3support -qt-libtiff -qt-libpng -qt-libjpeg -nomake demos -nomake examples -nomake tools -no-webkit -prefix /opt/qt4.6.3static
Всё успешно собралось и установилось.
Creator удалось поставить вот такой версии - qt-creator-linux-x86-gcc3.3-opensource-1.2.1.bin

Проект с программой успешно собрался, но release версия так работать и не захотела. Segmentation fault и всё тут.
Зато debug версия запустилась на ура.

Перетащил на чистый МСВС - не может найти и загрузить libstdc++.so.6
Утаскиваем и её. Положил рядом с бинарником, сделал симлинк ln -s libstdc++.so.6.0.3 /usr/lib/libstdc++.so.6

Всё завелось и полетело. Решить бы еще проблему с release версией... Но это уже не так страшно.

Метки записи: , 3 Комментарии
20Мар/120

[Еще вариант] Отправляем объект из внешней библиотеки в скрипт.

В первом варианте код был жестко завязан на интерфейсный класс плагина.

Как оказалось, можно обойтись и без него.
Для этого надо:
1. В плагине к конструктору добавить служебную конструкцию Q_INVOKABLE. Т.е. должно получиться так:

Q_INVOKABLE explicit ScriptObject(QObject *parent = 0);

А в основной программе нужно убрать строку с приведением qobject_cast и заменить строку с регистрацией объекта в движке на вот такую:

QScriptValue scObj = engine.newQObject(plugin->metaObject()->newInstance(), QScriptEngine::ScriptOwnership);

И всё! Никакой привязки к интерфейсу!

Теперь буду разбираться с тем, как бы всё это безобразие соединять сигналами. Как-нибудь по динамичнее.

upd: Не забываем в после засовывания объекта в скрипт его там зарегистрировать.

engine.globalObject().setProperty("ScObj", scObj);
Метки записи: , , Нет комментариев
20Мар/120

Отправляем объект из внешней библиотеки в скрипт

В Qt, как известно, есть замечательная вещь как QScript, позволяющая использовать ECMA скрипт.
В данный скриптовый движок возможно запихивать как отдельные функции, так и целые объекты.
А можно ли запихать в движок объект из внешней библиотеки (.dll, .so etc)?

Оказывается, что можно.

Метки записи: , , , Читать полностью
22Фев/120

const и все-все-все

char greeting[] = “Hello”;
char *p = greeting; 	// неконстантный указатель,
			// неконстантные данные
*p = "Bye";		// можно
++p;			// можно
const char *p = greeting; 	// неконстантный указатель,
				// константные данные
char const *p = greeting;	// то же самое
*p = "Bye";			// нельзя
++p;				// можно
char * const p = greeting; // константный указатель,
				// неконстантные данные
*p = "Bye";			// можно
++p;				// нельзя
const char * const p = greeting; 	// константный указатель,
					// константные данные
*p = "Bye";				// нельзя
++p;					// нельзя

Для функций-членов есть еще один модификатор

int foo() const	// гарантирует, что функция не модифицирует
			// содержимое класса
Метки записи: Нет комментариев
21Фев/120

QHash и структура в качестве ключа.

Тема легкая, но мне, почему-то далась достаточно напряжно.

Задача: использовать в качестве ключа QHash структуру.
Читаем документацию - для данной операции достаточно в структуре определить оператор "==" и написать глобальную функцию qHash для нашей структуры.

Решение:

struct MyStruct
{
    quint8 a1;
    quint8 a2;
    quint8 a3;
    quint8 a4;
    bool operator==(const MyStruct struc) const
    {
        return (a1 == struc.a1 &&
                a2 == struc.a2 &&
                a3 == struc.a3 &&
                a4 == struc.a4);
    }
};
uint qHash(const MyStruct &struc)
{
    //как-то вычисляем хеш
    //в моём случае в структуре содержалось 4 целых числа и я просто записал их в одно число со сдвигом
    uint result = struc.a1;

    result <<=(sizeof(quint8)*8);
    result = result|struc.a2;

    result <<=(sizeof(quint8)*8);
    result = result|struc.a3;

    result <<=(sizeof(quint8)*8);
    result = result|struc.a4;
    return result;
}

Использование:

QHash < MyStruct, QString > myQHash

Всё работает отлично.

А вот при попытке использовать еще одну структуру в качестве значения QHash

QHash < MyStruct, MyOtherStruct > myOtherQHash

При запросе значения по ключу - всё работает отлично, но при попытке получить ключ по значению получаем надпись:

no match for 'operator==' in 'i.QHash<Key, T>::const_iterator::value [with Key = MyStruct, T = MyOtherStruct]() == avalue'

Страшная надпись, не правда ли? :)

Причина - не хватает операции "==" во второй структуре. Добавляем её и всё работает.
Вот так.

struct, key, qhash

Метки записи: , Нет комментариев
10Фев/121

Получение произвольного бита из числа.

int bit = (c >> i) & 1

Где с - число, i - номер получаемого бита.

Метки записи: 1 комментарий
10Фев/120

Установка произвольного бита в числе.

b |= (1 << i);	// set
b &= ~(1 << i);	// clear

где b - число, а i - номер бита

Метки записи: Нет комментариев
3Фев/120

Слот. Поиск по QTreeWidget. Еще вариант.

Ищет по листьям. По первому столбцу.
Если дерево одноуровневое, то проверку на childCount можно убрать.

void MyClass::find(QString aFindString)
{
    QTreeWidgetItemIterator it(myTree);
    while (*it)
    {
        if (!(*it)->text(0).contains(aFindString, Qt::CaseInsensitive) && ((*it)->childCount() == 0))
        {
            (*it)->setHidden(true);
        }
        else
        {
            (*it)->setHidden(false);
        }
        ++it;
    }
}

Коннект идентичен.

QLineEdit *findEdit = new QLineEdit(this);
connect(findEdit,SIGNAL(textEdited(QString)),this,SLOT(find(QString)));

Должно работать гораздо быстрее первого варианта :)

Метки записи: , , Нет комментариев
27Янв/120

Слот. Поиск по QTreeWidget.

Поиск работает только в одноуровневом дереве по первому столбцу.

void MyClass::find(QString aFindString)
{
    int childCount = tree->invisibleRootItem()->childCount();
    if(aString != "")
    {
        QList <QTreeWidgetItem *> findList = tree->findItems(aFindString, Qt::MatchContains, 0);
        for(int i = 0; i < childCount; i++)
        {
            tree->invisibleRootItem()->child(i)->setHidden(true);
        }
        int findListSize = findList.size();
        for(int j = 0; j < findListSize; j++)
        {
            findList.at(j)->setHidden(false);
        }
    }
    else
    {
        for(int i = 0; i < childCount; i++)
        {
            tree->invisibleRootItem()->child(i)->setHidden(false);
        }
    }
}

Коннектим так:

QLineEdit *findEdit = new QLineEdit(this);
connect(findEdit,SIGNAL(textEdited(QString)),this,SLOT(find(QString)));
Метки записи: , , Нет комментариев
28Дек/110

Интерактивный курс по JavaScript

Отлично и интересно сделанный!
Буду изучать...

На английском Codecademy

Метки записи: Нет комментариев