crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

10 страниц V  « < 5 6 7 8 9 > »   
Ответить в данную темуНачать новую тему
> Секреты и интересные возможности Qt
SABROG
  опции профиля:
сообщение 23.2.2010, 16:36
Сообщение #61


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Кроссплатформенный метод установки приоритета для приложени. Навеяно этим постом.

Вариант 1.
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qApp->thread()->setPriority(QThread::HighestPriority);
    return a.exec();
}


Вариант 2. Установка приоритета после входа в цикл событий.
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include <QtCore/QMetaType>

Q_DECLARE_METATYPE(QThread::Priority)
class CoreApplication : public QCoreApplication
{
        Q_OBJECT;
public:
        CoreApplication(int& argc, char* argv[], QThread::Priority priority = QThread::InheritPriority)
            : QCoreApplication(argc, argv)
        {
            qRegisterMetaType<QThread::Priority>();
            connect(this, SIGNAL(priorityChanged(QThread::Priority)),
                            SLOT(changePriority(QThread::Priority)),
                            Qt::QueuedConnection);
            if (priority != QThread::InheritPriority)
                setPriority(priority);
        }

        inline void setPriority(QThread::Priority priority) {emit priorityChanged(priority);}
        inline QThread::Priority priority() const {return thread()->priority();}
protected slots:
        void changePriority(QThread::Priority priority)
        {
            thread()->setPriority(priority);
        }
signals:
        void priorityChanged(QThread::Priority priority);
};

int main(int argc, char *argv[])
{
    CoreApplication a(argc, argv, QThread::HighestPriority);
    return a.exec();
}

#include "main.moc"

Вариант 3. Более легковесный вариант установки приоритета после входа в цикл событий, если вместо класса Object будет какой-нибудь MainWindow.
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>

class Object : public QObject
{
    Q_OBJECT;
public:
    Object(QObject *parent = 0) : QObject(parent) {}
    void setThreadPriority(QThread::Priority priority)
    {
        QMetaObject::invokeMethod(this, "changePriority", Qt::QueuedConnection, Q_ARG(int, static_cast<int>(priority)));
    }
protected:
    Q_INVOKABLE void changePriority(int priority)
    {
        qApp->thread()->setPriority(static_cast<QThread::Priority>(priority));
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
        Object object;
        object.setThreadPriority(QThread::HighestPriority);
    return a.exec();
}

#include "main.moc"


Для Windows стоит разделять понятия "класс приоритета приложения" и "приоритет потока". Все приложения изначально получают класс приоритета NORMAL_PRIORITY_CLASS и приоритет потока THREAD_PRIORITY_NORMAL. Предположим, что мы вызываем метод QThread::setPriority(QThread::TimeCriticalPriority), чтобы выделить самый высокий приоритет. К нашему удивлению в том же TaskManager'e приоритет будет стоять "Средний". Но в Windows количество возможных приоритетов аж 31 штука. Самый высокий достигается комбинацией установки класса REALTIME_PRIORITY_CLASS и приоритета THREAD_PRIORITY_TIME_CRITICAL. В Qt нет возможности установки класса приоритета, поэтому решением может быть вызов WINAPI ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);, или установка класса через TaskManager, или установка класса приоритета в момент запуска приложения:

start /REALTIME myprogram.exe


Установка приоритета приложения для linux может не работать в некоторых ситуациях о чем сказано в документации к метод QThread::setPriority().

Сообщение отредактировал SABROG - 23.2.2010, 16:58
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 23.2.2010, 19:22
Сообщение #62


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Ну собственно один вариант ещё и в списке рассылке, Где создаётся пользовательское событие.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 23.2.2010, 19:39
Сообщение #63


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(SergSh @ 27.8.2009, 9:49) *
Чтобы этого не происходило достаточно воспользоваться setGridSize().


Предпочтительней для этих целей использовать метод QListView::setUniformItemSizes(true), эффект аналогичный.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 2.4.2010, 0:05
Сообщение #64


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Выложу сегодня 2 полезных "хака", которые могут пригодится при отладке приложения:

Первый хак - для доступа к приватным классам Qt:

namespace Hack { template <class To, class From> inline To* d_ptr(From* ptr){ return (To*)QObjectPrivate::get(ptr);}}


Эту функцию можно использовать например для включения функционала в QLineEdit, который пишет текст типа "введите сюда что-нибудь", когда в QLineEdit ничего нет:
#include "private/qlineedit_p.h"
...
{
    Hack::d_ptr<QLineEditPrivate>(ui->lineEdit)->placeholderText = "Test";
}


Или для установки своего виджета вместо QTableCornerButton в QTableView:

#include "private/qtableview_p.h"
...
QLabel* label = new QLabel(ui->tableWidget);
label->setText("<span style=\"color: red\">Bye</span> <span style=\"color: green\">Bye</span>, <span style=\"color: blue\">World!</span>");
label->setAlignment(Qt::AlignCenter);
QTableViewPrivate* tvPrivate = Hack::d_ptr<QTableViewPrivate>(ui->tableWidget);
tvPrivate->cornerWidget->deleteLater();
tvPrivate->cornerWidget = label;


Второй хак - для перевода перечеслений области имен Qt в текстовые строки:

struct StaticQtMetaObject : public QObject
{
    static inline const QMetaObject& get() {return staticQtMetaObject;}
};


Использовать так:

#include <QtCore/QtGlobal>
#include <QtCore/QtDebug>
#include <QtCore/QMetaEnum>

struct StaticQtMetaObject : public QObject
{
    static inline const QMetaObject& get() {return staticQtMetaObject;}
};

int main(int argc, char *argv[])
{
    const QMetaObject& mo = StaticQtMetaObject::get();
    int index = mo.indexOfEnumerator("Key");
    QMetaEnum me = mo.enumerator(index);
    Qt::Key myKey = Qt::Key_F35;
    qDebug() << me.valueToKey(myKey);
    return 0;
}


Методы опробованы на Qt версии 4.6.2, в других версиях они могут не работать.

Сообщение отредактировал SABROG - 3.4.2010, 8:28
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
loz
  опции профиля:
сообщение 11.4.2010, 8:56
Сообщение #65


Новичок


Группа: Новичок
Сообщений: 2
Регистрация: 10.4.2010
Пользователь №: 1615

Спасибо сказали: 2 раз(а)




Репутация:   0  


Думаю что в данной теме необходимо упомянуть об интересной возможности Qt - функции прямого копировани участков памяти :
void *qMemCopy(void* dest, const void* src, size_t n)

Данная функция копирует n байт из src в dest. Разумеется, вся ответственность за проверку размеров лежит на программисте.

Для примера использования могу показать приведение типов, обычными способами которое производится довольно трудоемко, а именно - мне надо было работать со строками в их битовом представлении. В Qt есть два класса - QString и QBitArray, возможности нормальной конвертации данных между ними я найти не смог, а требование к производительности кода было достаточно высоко, пришлось сделать так:
inline QString bitsToString(QBitArray& arr) {
        QString r;
        r.resize(arr.size() / 16);   // длина массива должна быть точно кратна размеру символа в UTF-16, 16 битам
        qMemCopy(r.data_ptr()->data, arr.data_ptr()->data+1, r.length()*2);   // т.к. 1 символ = 2 байта
        return(r);
};

inline QBitArray stringToBits(const QString& str) {
        QBitArray r(str.length()*16);    // 16 бит в символе
        qMemCopy(r.data_ptr()->data+1, str.constData(), str.length()*2);
        return (r);
}


И здесь еще есть инетересная особенность класса QBitArray, как вы заметили для обращения к данным в нем мы прибавляли к указателю 1, т.е. данны идут со второго байта, но почему?
А потому, что биты из QBitArray хранятся как реальные биты, но т.к. в памяти минимальная еденица хранения - байт, то что же делать с массивом например из 9 бит?
Так вот в этом первом байте как раз хранится количество используемых бит последнего байта массива. Все просто =)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 17.4.2010, 15:48
Сообщение #66


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Цитата(SABROG @ 2.4.2010, 1:05) *
Выложу сегодня 2 полезных "хака", которые могут пригодится при отладке приложения:

Первый хак - для доступа к приватным классам Qt:

namespace Hack { template <class To, class From> inline To* d_ptr(From* ptr){ return (To*)QObjectPrivate::get(ptr);}}


Эту функцию можно использовать например для включения функционала в QLineEdit, который пишет текст типа "введите сюда что-нибудь", когда в QLineEdit ничего нет:
#include "private/qlineedit_p.h"
...
{
    Hack::d_ptr<QLineEditPrivate>(ui->lineEdit)->placeholderText = "Test";
}

Вот у меня 2 вопроса :
что делает функция этого тимплейта?возвращает указатель на метод приватного класса по имени метода?(с тимплейтами знаком поверхностно, и с указателями на функции практически так же)
и 2ой :
Я так понимаю, метод и пропертя placeholderText для QLineEdit будет только в версии 4.7 ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 19.4.2010, 12:13
Сообщение #67


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(Andrewshkovskii @ 17.4.2010, 16:48) *
что делает функция этого тимплейта?

Возвращает указатель, который содержится в d_ptr переменной и приводит его к одному из приватному базовому классу. Например для QLineEdit можно получить сразу 3 приватных класса: QLineEditPrivate, QWidgetPrivate, QObjectPrivate. Нужный можно выбрать.

Цитата(Andrewshkovskii @ 17.4.2010, 16:48) *
Я так понимаю, метод и пропертя placeholderText для QLineEdit будет только в версии 4.7 ?

Да.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 24.4.2010, 11:55
Сообщение #68


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Администратор одного программерского форума удалил мой блог, который я вел 2 года. Там был код, который я выкладывал в постах. Никакие кэши гугла и archive.org не сохранили информацию. В общем, если вы не против, то буду тут периодически выкладывать интересные/полезные решения.
---

Добавление сигнала clicked() в QLabel средствами State Machine Framework:

    QStateMachine* machine = new QStateMachine(this);
    QState* s1 = new QState(machine);
    QMouseEventTransition* mouseTrans =
            new QMouseEventTransition(ui->label, QEvent::MouseButtonRelease, Qt::LeftButton, s1);
    QObject::connect(mouseTrans, SIGNAL(triggered()), msgBox, SLOT(show()));
    machine->setInitialState(s1);
    machine->start();



Добавление флагов в свой класс на базе QObject'a и вывод состояния флагов в консоль:

// myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H

#include <QtCore/QObject>
class MyClass : public QObject
{
    Q_OBJECT
    Q_FLAGS(MyMode)

public:
    MyClass(QObject* parent = 0);

    enum MyModeFlag {
        NoOptions = 0,
        Option1 =   1L << 0,
        Option2 =   1L << 1,
        Option3 =   1L << 2,
        Option4 =   1L << 3,
        Option5 =   1L << 4
    };

    Q_DECLARE_FLAGS(MyMode, MyModeFlag)

    void setMode(MyMode m);
    inline MyMode mode() const;

private:
    MyMode m_mode;
};

Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::MyMode)

inline MyClass::MyMode MyClass::mode() const {return m_mode;}

class QDebug;
QDebug operator << (QDebug debug, MyClass::MyMode mode);

#endif // MYCLASS_H


// myclass.cpp

#include <QtCore/QDebug>
#include <QtCore/QMetaEnum>

#include "myclass.h"


MyClass::MyClass(QObject* parent)
        : QObject(parent), m_mode(MyClass::NoOptions)
{
}

void MyClass::setMode(MyMode m)
{
    m_mode = m;
}

QDebug operator << (QDebug debug, MyClass::MyMode modes)
{
    const QMetaObject& mo = MyClass::staticMetaObject;
    int index = mo.indexOfEnumerator("MyMode");
    QMetaEnum me = mo.enumerator(index);
    debug << me.valueToKeys(modes);
    return debug;
}


Результат:

"Option1|Option3|Option5"


Сообщение отредактировал SABROG - 24.4.2010, 17:23
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 24.4.2010, 12:11
Сообщение #69


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Да, я тоже заметил, что удалили. Хотел инфу кое-какую почитать..и на тебе..:)А почему удалили, не сказали?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 24.4.2010, 12:11
Сообщение #70


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата( SABROG)
Администратор одного программерского форума удалил мой блог, который я вел 2 года
. Имеешь в виду свой блог на vingrade. Очень жаль. Заглядывал иногда. Они как нибудь обосновали свои действия?

З,Ы, Может и нам расширение для блогов поставить?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

10 страниц V  « < 5 6 7 8 9 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 5:14