Russian Qt Forum

Qt => Общие вопросы => Тема начата: zoro86 от Март 13, 2010, 08:37



Название: QBitArray есть вопрос?
Отправлено: zoro86 от Март 13, 2010, 08:37
Есть более простой способ как загнать HEX код типа 09 или 4B в QBitArray?
картина такова что мне в ответ устройстово выдает один байт, надо перевести в биты и прочесть каждый на различные статусы... соответственно после перевода должно получится 8 бит ???


Название: Re: QBitArray есть вопрос?
Отправлено: SABROG от Март 13, 2010, 10:04
Самый быстрый способ это static_cast из QByteArray в QBitArray. К сожалению об этом не пишут в документации и возможно в будущем могут появится дополнительные члены в QBitArray классе.


Название: Re: QBitArray есть вопрос?
Отправлено: zoro86 от Март 13, 2010, 12:53
SABROG попробовал сделать так QBitArray *bitArray = static_cast<QByteArray *> (&baTmp);
выдает ошибку при компиляции и пишет...
cannot convert 'QByteArray*' to 'QBitArray*' in initialization


Название: Re: QBitArray есть вопрос?
Отправлено: MoPDoBoPoT от Март 13, 2010, 13:30
zoro86, static_cast из QByteArray в QBitArray это:
Код
C++ (Qt)
...
QByteArray *byteArray;
...
QBitArray *bitArray = static_cast<QBitArray *> (byteArray);
...
 


Название: Re: QBitArray есть вопрос?
Отправлено: zoro86 от Март 13, 2010, 14:34
такая же ошибка ???


Название: Re: QBitArray есть вопрос?
Отправлено: BRE от Март 13, 2010, 15:24
такая же ошибка ???
Так и должно быть.
static_cast<Type>( val ) это совсем не аналог сишного (Type)val.
Есть определенные правила работы static_cast и в эти правила не входит преобразование из QByteArray в QBitArray.
Почитай про static_cast побольше.  ;)


Название: Re: QBitArray есть вопрос?
Отправлено: denka от Март 13, 2010, 16:40
Есть более простой способ как загнать HEX код типа 09 или 4B в QBitArray?
картина такова что мне в ответ устройстово выдает один байт, надо перевести в биты и прочесть каждый на различные статусы... соответственно после перевода должно получится 8 бит ???
А возможностей самого языка разве для этого мало? Зачем тут огород из классов?


Название: Re: QBitArray есть вопрос?
Отправлено: Igors от Март 13, 2010, 17:09
Почитай про static_cast побольше.  ;)
Почитай что/где? Стандарт? Там не так уж легко разобраться  :)
Вот напр. доступное изложение http://alenacpp.blogspot.com/2005/08/c.html (http://alenacpp.blogspot.com/2005/08/c.html)
Цитировать
static_cast между указателями корректно, только если один из указателей - это указатель на void или если это приведение между объектами классов, где один класс является наследником другого.
Привести через указатель - вероятно будет все Ok, по данным оба выглядят одинаково. Но это нелегальщина. Я бы вообще обошелся без QBitAtay, сделав пару-тройку ф-ций
Код:
inline bool GetBit( const QByteArray & a, int bitIndex )
{
 return a[bitIndex / 8] & (1 << (bitIndex % 8)) != 0;
}

inline void SetBit( QByteArray & a, int bitIndex )
{
 a[bitIndex / 8]  |= (1 << (bitIndex % 8));
}

inline void ClrBit( QByteArray & a, int bitIndex )
{
 a[bitIndex / 8]  &= ~(1 << (bitIndex % 8));
}

inline void SetBit( QByteArray & a, int bitIndex, bool doSet )
{
 if (doSet) SetBit(a, bitIndex);
 else ClrBit(a, bitIndex);
}


Название: Re: QBitArray есть вопрос?
Отправлено: BRE от Март 13, 2010, 17:48
Почитай что/где? Стандарт? Там не так уж легко разобраться  :)
Почему стандарт? Не обязательно стандарт, но можно и его....
А так есть книги, статьи и куча заметок в инете.
Достаточно в google набрать это слово.

Вот напр. доступное изложение http://alenacpp.blogspot.com/2005/08/c.html (http://alenacpp.blogspot.com/2005/08/c.html)
Вот-вот.  ;)

Я бы вообще обошелся без QBitAtay, сделав пару-тройку ф-ций
или посмотреть на QFlags.


Название: Re: QBitArray есть вопрос?
Отправлено: SABROG от Март 14, 2010, 04:27
Если глянуть исходники, то там еще публичный указатель есть на QByteArray. Можно вообще без приведения типов работать. static_cast не работает скорее всего потому, что QBitArray не наследует QByteArray, а использует аггрегацию. Тогда наверно все-таки reinterpret_cast.


Название: Re: QBitArray есть вопрос?
Отправлено: zoro86 от Март 15, 2010, 07:49
ну в общем поюзал там и тут получилась так..

void AV268Acceptor::dec_to_bin(const int decimal)
{
    int remainder;

            if(decimal <= 1) {
                result_bits[count_bit] = decimal;
                count_bit --;
                return;
            }

            remainder = decimal%2;
            result_bits[count_bit] = remainder;
            count_bit --;
            dec_to_bin(decimal >> 1);
            return;
}
void  AV268Acceptor::bits(const int decimal)
{

    count_bit = 7;

    dec_to_bin(decimal);
    qDebug() << result_bits[0];
    qDebug() << result_bits[1];
    qDebug() << result_bits[2];
    qDebug() << result_bits[3];
    qDebug() << result_bits[4];
    qDebug() << result_bits[5];
    qDebug() << result_bits[6];
    qDebug() << result_bits[7];

}
{
    ...
    unsigned char ff = 0x1B;
    int aa = ff;
    bits(aa);
   ...
}
где int count_bit;  QBitArray result_bits; public переменные...
если есть идеи как можно по другому, к примеру проста считать 3-bit из byta=0x1B пишите...


Название: Re: QBitArray есть вопрос?
Отправлено: kuzulis от Март 15, 2010, 08:56
А не проще ли маскированием выделять нужные биты нежели юзать бит-аррай ? :)
И причем тут hex код?


Название: Re: QBitArray есть вопрос?
Отправлено: p166 от Март 15, 2010, 22:06
Ребята! Юзайте битовые маски! Зачем велосипед изобретать? Столько кода лишнего.... жесть...


Название: Re: QBitArray есть вопрос?
Отправлено: zoro86 от Март 16, 2010, 06:29
Скинте пример... или сылку, я таким еще не пользовался..


Название: Re: QBitArray есть вопрос?
Отправлено: voronElf от Март 16, 2010, 10:07
Например:
Код:
#define MASK_1 0x02
char bytes = .... //получение байта
if(bytes & MASK_1) {
  ... //первый бит установлен в 1 (нумерация битов с нуля начинается справал налево)
};

Почитай про битовые операции в С


Название: Re: QBitArray есть вопрос?
Отправлено: sne от Март 17, 2010, 10:57
Код:
#ifndef BITARRAYEXT_H
#define BITARRAYEXT_H

#include <QtCore/QBitArray>

class QString;
class QBitArray;
class QByteArray;

class BitArrayExt
{
public:
    inline BitArrayExt() {}
    explicit inline BitArrayExt(const QBitArray &other) { m_bits = other; }
    inline BitArrayExt(int size, bool value = false) { m_bits.fill(value, size); }
    inline BitArrayExt(const BitArrayExt &other) { m_bits = other.m_bits; }
    inline BitArrayExt &operator=(const BitArrayExt &other) { m_bits = other.m_bits; return *this; }

    static BitArrayExt fromByteArray(const QByteArray &bytes);
    static BitArrayExt fromChar(const char ch);
    static BitArrayExt fromShort(const qint16 val);
    static BitArrayExt fromInt32(const qint32 val);
    static BitArrayExt fromInt64(const qint64 val);
    inline QBitArray toBitArray() { return m_bits; }
    QString toString();

private:
    QBitArray m_bits;
};

#endif // BITARRAYEXT_H

Код:
#include "bitarrayext.h"
#include <QtCore/QString>
#include <QtCore/QByteArray>

BitArrayExt BitArrayExt::fromByteArray(const QByteArray &bytes)
{
    QBitArray bits;

    foreach (char ch, bytes) {
        int inc_size = sizeof(char) * 8;
        int base_size = bits.size();

        bits.resize(bits.size() + inc_size);
        for (int i = 0; i < inc_size; i++) {
            bits[base_size + i] = ((ch & (1 << i)) >> i);
        }
    }

    return BitArrayExt(bits);
}

BitArrayExt BitArrayExt::fromChar(const char ch)
{
    return fromByteArray(QByteArray(&ch, sizeof(char)));
}

BitArrayExt BitArrayExt::fromShort(qint16 val)
{
    return fromByteArray(QByteArray(reinterpret_cast<char *>(&val), sizeof(qint16)));
}

BitArrayExt BitArrayExt::fromInt32(qint32 val)
{
    return fromByteArray(QByteArray(reinterpret_cast<char *>(&val), sizeof(qint32)));
}

BitArrayExt BitArrayExt::fromInt64(qint64 val)
{
    return fromByteArray(QByteArray(reinterpret_cast<char *>(&val), sizeof(qint64)));
}

QString BitArrayExt::toString()
{
    QString s;

    for (int i = 0; i < m_bits.size(); i++)
        s += m_bits.at(i) ? '1' : '0';

    return s;
}

Может быть кому пригодится.


Название: Re: QBitArray есть вопрос?
Отправлено: p166 от Март 18, 2010, 15:19
Вот два примера по использованию битовых масок.
1 - getRights() - возвращает ulong где первые 8 бит являются флагами
2 - setRights(ulong rights) - читает 8 бит ulong и вывешивает соответствующие флаги.
Для наглядности работа функций реализована немного по разному.

Код:
ulong WFIL_req::getRights()
{
    ulong rights=0;

    if (ui->cb0->isChecked()) rights |= 1<<0; else rights |= 0<<0;
    if (ui->cb1->isChecked()) rights |= 1<<1; else rights |= 0<<1;
    if (ui->cb2->isChecked()) rights |= 1<<2; else rights |= 0<<2;
    if (ui->cb3->isChecked()) rights |= 1<<3; else rights |= 0<<3;
    if (ui->cb4->isChecked()) rights |= 1<<4; else rights |= 0<<4;
    if (ui->cb5->isChecked()) rights |= 1<<5; else rights |= 0<<5;
    if (ui->cb6->isChecked()) rights |= 1<<6; else rights |= 0<<6;
    if (ui->cb7->isChecked()) rights |= 1<<7; else rights |= 0<<7;
    if (ui->cb8->isChecked()) rights |= 1<<8; else rights |= 0<<8;

    return rights;
}

void WFIL_req::setRights(ulong rights)
{
    if (rights&0x1) ui->cb0->setChecked(true); else ui->cb0->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb1->setChecked(true); else ui->cb1->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb2->setChecked(true); else ui->cb2->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb3->setChecked(true); else ui->cb3->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb4->setChecked(true); else ui->cb4->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb5->setChecked(true); else ui->cb5->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb6->setChecked(true); else ui->cb6->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb7->setChecked(true); else ui->cb7->setChecked(false);
    rights >>= 1;
    if (rights&0x1) ui->cb8->setChecked(true); else ui->cb8->setChecked(false);
}


Название: Re: QBitArray есть вопрос?
Отправлено: voronElf от Март 19, 2010, 07:16
p166, не сочтите за наезд, но не проще ли вместо маски в 0х01 везде прописать константы с нужным битом (0х01, 0x02, 0x04 ...) ?
нагляднее и на операциях сдвига экономия ...

Код:
rights |= 0x01;
rights |= 0x02;
rights |= 0x04;
rights |= 0x08;
rights |= 0x10;
...

if (rights & 0x01) ...
if (rights & 0x02) ...
if (rights & 0x04) ...
if (rights & 0x10) ...


Название: Re: QBitArray есть вопрос?
Отправлено: p166 от Март 19, 2010, 14:14
voronElf, полностью согласен с тобой, но как я писал выше:
Цитировать
Для наглядности работа функций реализована немного по разному.

Это удобно если читаешь биты в цикле, выглядит нагляднее и на операциях сдвига описаниях констант экономия ...
:)

Код:
for (int i=0; i<sizeof(ulong)*8; i++)
{
   if (rights&0x1) {do ...}
   rights >>= 1;
}
PS: isnt it?

PS2: поправился :)


Название: Re: QBitArray есть вопрос?
Отправлено: voronElf от Март 19, 2010, 14:27
в цикле да, согласен

ПС: sizeof(ulong) возвращает количество битов ? не знал ....