2017-09-23 10 views
0

最近私は自分のハードウェア用のデバッガを作成しています。 eclipseやqtの作成者や他のIDEのようなメモリビューアウィジェットを追加したいと思います。しかし、私はどのような種類のウィジェットを使うのか分かりません。QTで自分自身のメモリビューアを実現する方法

enter image description here

enter image description here

+0

例を見つけるでしょう、あなたは、第一または第二の画像を取得したいですか? – eyllanesc

+0

2つの質問:1:最初の画像を取得します。 2 2番目のイメージのようなウィンドウを実現しましたが、2番目のイメージのようにテキストの色を変更する方法を理解していません –

+0

質問は独立しているので、パートごとに質問することをお勧めします。 – eyllanesc

答えて

2

最良のオプションは、タスクがプライベートで、ウィジェットのどれもが収納されていないので、カスタムウィジェットを作成することです。たとえば、tableWidgetは、いくつかの設定は、このようにそれを作ることがありますタスクに

これをQAbstractScrollAreaから継承し、このクラスからQTableView、QListView、QListWidget、QTableWidgetを継承します。 QScrollArea内にデータを表示するように設計されています。 さらに、このクラスのdocumentationはカスタムクラスを作成する方法を教えてくれます。

  • がその動きを追跡し、その範囲、値、ページのステップ、および を設定することで、スクロールバーを制御します。QAbstractScrollAreaを継承する場合

    は、次の操作を行う必要があります。

  • スクロールバーの値に従って、 ビューポートに領域の内容を描画します。
  • viewportEvent()内のビューポートによって受信された イベントを処理します。
  • 特にサイズ変更イベント。 ビューポートの内容を更新するには、viewport-> update()を使用してください。すべてのペイント操作がビューポート上で行われるため、update()の が代わりに使用されます。

    memoryviewer.h

    #ifndef MEMORYVIEWER_H 
    #define MEMORYVIEWER_H 
    
    #include <QAbstractScrollArea> 
    #include <QBuffer> 
    
    class MemoryViewer : public QAbstractScrollArea 
    { 
        Q_OBJECT 
    public: 
        MemoryViewer(QWidget *parent = 0); 
        ~MemoryViewer(); 
    
        void setData(const QByteArray &ba); 
        bool setData(QIODevice &device); 
    
    protected: 
        void paintEvent(QPaintEvent *); 
        void resizeEvent(QResizeEvent *); 
    
    private: 
        void adjustContent(); 
        void init(); 
    
        int addressWidth(); 
        int hexWidth(); 
        int asciiWidth(); 
    
        QByteArray data(qint64 pos=0, qint64 count=-1); 
    
        int nBlockAddress; 
        int mBytesPerLine; 
    
        int pxWidth; 
        int pxHeight; 
    
        qint64 startPos; 
        qint64 endPos; 
    
        int nRowsVisible; 
    
        QBuffer buffer; 
        QIODevice *ioDevice; 
        qint64 size; 
    
        QByteArray dataVisible; 
        QByteArray dataHex; 
    }; 
    
    #endif // MEMORYVIEWER_H 
    

    memoryviewer.cpp

    #include "memoryviewer.h" 
    
    #include <QPainter> 
    #include <QScrollBar> 
    
    MemoryViewer::MemoryViewer(QWidget *parent):QAbstractScrollArea(parent) 
    { 
        ioDevice = new QBuffer(this); 
        init(); 
        connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &MemoryViewer::adjustContent); 
        connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &MemoryViewer::adjustContent); 
    } 
    
    MemoryViewer::~MemoryViewer() 
    { 
    
    } 
    
    
    void MemoryViewer::init() 
    { 
        nBlockAddress = 2; 
        mBytesPerLine = 16; 
    
        pxWidth = fontMetrics().width(QChar('0')); 
        pxHeight = fontMetrics().height(); 
    
    } 
    
    int MemoryViewer::addressWidth() 
    { 
        return (nBlockAddress*4+ nBlockAddress -1)*pxWidth; 
    } 
    
    int MemoryViewer::hexWidth() 
    { 
        return (mBytesPerLine*3+1)*pxWidth; 
    } 
    
    int MemoryViewer::asciiWidth() 
    { 
        return (mBytesPerLine*2 +1)*pxWidth; 
    } 
    
    QByteArray MemoryViewer::data(qint64 pos, qint64 count) 
    { 
        QByteArray buffer; 
    
        if (pos >= size) 
         return buffer; 
    
        if (count < 0) 
         count = size; 
        else 
         if ((pos + count) > size) 
          count = size - pos; 
    
        if(ioDevice->open(QIODevice::ReadOnly)){ 
         ioDevice->seek(pos); 
         buffer = ioDevice->read(count); 
         ioDevice->close(); 
        } 
        return buffer; 
    } 
    
    void MemoryViewer::setData(const QByteArray &ba) 
    { 
        buffer.setData(ba); 
        setData(buffer); 
    
    } 
    
    bool MemoryViewer::setData(QIODevice &device) 
    { 
        ioDevice = &device; 
        bool ok = ioDevice->open(QIODevice::ReadOnly); 
        if(ok){ 
         size = ioDevice->size(); 
         ioDevice->close(); 
        } 
        else{ 
         QBuffer *buf = new QBuffer(this); 
         ioDevice = buf; 
        } 
        init(); 
        adjustContent(); 
        return ok; 
    } 
    
    void MemoryViewer::resizeEvent(QResizeEvent *) 
    { 
        adjustContent(); 
    } 
    
    
    void MemoryViewer::paintEvent(QPaintEvent *) 
    { 
        QPainter painter(viewport()); 
    
        int offsetX = horizontalScrollBar()->value(); 
    
        int y = pxHeight; 
        QString address; 
    
        painter.setPen(viewport()->palette().color(QPalette::WindowText)); 
    
        for(int row = 0; row <= dataVisible.size()/mBytesPerLine; row++){ 
         QString str = QString("%1").arg(startPos + mBytesPerLine*row, nBlockAddress*4, 16, QChar('0')).toUpper(); 
         int i = 0; 
         address = ""; 
         while(i < nBlockAddress){ 
          address += str.mid(i*4, 4) + ":"; 
          i++; 
         } 
         address.remove(address.size()-1, 1); 
    
         painter.drawText(pxWidth/2 -offsetX , y, address); 
         y+=pxHeight; 
        } 
    
        int x; 
        int lx = addressWidth() +pxWidth; 
        painter.drawLine(lx-offsetX, 0, lx-offsetX, height()); 
        lx += pxWidth/2; 
        y = pxHeight; 
    
        //hex data 
        x = lx-offsetX+3*pxWidth; 
        int w = 3*pxWidth; 
        for(int col =0; col < mBytesPerLine/2; col++){ 
         painter.fillRect(x-pxWidth/2, 0, w, height(), viewport()->palette().color(QPalette::AlternateBase)); 
         x+= 6*pxWidth; 
        } 
    
        int bPos = 0; 
        for(int row=0; row < nRowsVisible; row++){ 
         x = lx-offsetX; 
         for(int col =0; (col < mBytesPerLine) && (bPos < dataHex.size()) ; col++){ 
          QString str = dataHex.mid(bPos*2,2).toUpper(); 
          painter.drawText(x, y, str); 
          x += 3*pxWidth; 
          bPos += 1; 
         } 
         y+= pxHeight; 
        } 
    
        lx = addressWidth() + hexWidth(); 
        painter.drawLine(lx-offsetX, 0, lx-offsetX, height()); 
    
        lx += pxWidth/2; 
    
        bPos = 0; 
        y = pxHeight ; 
        int ch; 
        for(int row=0; row < nRowsVisible; row++){ 
         x = lx-offsetX; 
         for(int col =0; (col < mBytesPerLine) && (bPos < dataVisible.size()) ; col++){ 
          ch = (uchar)dataVisible.at(bPos); 
          if (ch < 0x20) 
           ch = '.'; 
          painter.drawText(x, y, QChar(ch)); 
          x += 2*pxWidth; 
          bPos += 1; 
         } 
         y+= pxHeight; 
        } 
    } 
    
    void MemoryViewer::adjustContent() 
    { 
        int w = addressWidth() + hexWidth() + asciiWidth(); 
        horizontalScrollBar()->setRange(0, w - viewport()->width()); 
        horizontalScrollBar()->setPageStep(viewport()->width()); 
    
        nRowsVisible = viewport()->height()/pxHeight; 
        int val = verticalScrollBar()->value(); 
        startPos = (qint64)val*mBytesPerLine; 
        endPos = startPos + nRowsVisible*mBytesPerLine -1; 
    
        int lineCount = size/mBytesPerLine; 
        verticalScrollBar()->setRange(0, lineCount-nRowsVisible); 
        verticalScrollBar()->setPageStep(nRowsVisible); 
    
        if(endPos >= size){ 
         endPos = size-1; 
        } 
        dataVisible = data(startPos, endPos-startPos + mBytesPerLine +1); 
        dataHex = dataVisible.toHex(); 
        viewport()->update(); 
    } 
    

    アドバ:その参照を取る

私は、次のウィジェットを作成しました実装では、QIODeviceから継承するオブジェクト、たとえばQFileを渡し、メモリオーバーヘッドを排除してビューに必要なときにデータを読み込むことができるため、すべてのバイトを直接ロードする必要はありません。さらに、次のではQByteArray

を渡すことができlink、あなたの質問は何ですか

enter image description here

+0

本当に本当にありがとうございます。私の言葉を超えて〜 –

関連する問題