Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何通过QT实现我自己的内存查看器_C++_Qt_Qt5 - Fatal编程技术网

C++ 如何通过QT实现我自己的内存查看器

C++ 如何通过QT实现我自己的内存查看器,c++,qt,qt5,C++,Qt,Qt5,最近我正在为自己的硬件编写一个调试器。我想添加一个内存查看器小部件,比如eclipse、QtCreator或其他IDE。然而,我不知道该使用什么样的小部件。例如,tableWidget,是否有如下设置: 最好的选择是创建一个自定义小部件,因为任务是私有的,并且没有一个小部件适合任务 为此,我们将从QAbstractScrollArea继承,从这个类继承QTableView、QListView、QListWidget和QTableWidget。其设计用于在QScrolla区域内显示数据。 此外,

最近我正在为自己的硬件编写一个调试器。我想添加一个内存查看器小部件,比如eclipse、QtCreator或其他IDE。然而,我不知道该使用什么样的小部件。例如,tableWidget,是否有如下设置:


最好的选择是创建一个自定义小部件,因为任务是私有的,并且没有一个小部件适合任务

为此,我们将从QAbstractScrollArea继承,从这个类继承QTableView、QListView、QListWidget和QTableWidget。其设计用于在QScrolla区域内显示数据。 此外,这个类告诉我们如何创建自定义类

继承QAbstractScrollArea时,需要执行以下操作:

  • 通过设置滚动条的范围、值、页面步长和 跟踪他们的行动
  • 在中绘制区域的内容 根据滚动条的值创建视口
  • 处理事件 由viewportEvent()中的视口接收
  • 显著地调整事件的大小。 使用viewport->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
\ifndef MEMORYVIEWER\u H
#定义MEMORYVIEWER\u H
#包括
#包括
类MemoryViewer:公共QabstructScrollArea
{
Q_对象
公众:
MemoryView(QWidget*parent=0);
~MemoryViewer();
无效设置数据(常数QByteArray和ba);
bool setData(设备和装置);
受保护的:
无效油漆事件(QPaintEvent*);
void resizeEvent(QResizeEvent*);
私人:
无效内容();
void init();
int addressWidth();
int hexWidth();
int asciwidth();
QByteArray数据(qint64位置=0,qint64计数=-1);
地址;
int mBytesPerLine;
宽度;
智力高度;
秦皇岛64号卫星;
qint64 endPos;
int-nRowsVisible;
缓冲区;
QIODevice*碘设备;
秦T64大小;
QByteArray数据可见;
QByteArray数据十六进制;
};
#endif//MEMORYVIEWER\u 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();
}
#包括“memoryviewer.h”
#包括
#包括
MemoryView::MemoryView(QWidget*父项):QBStractScrollArea(父项)
{
ioDevice=新的QBuffer(此);
init();
连接(垂直滚动条(),&QScrollBar::valueChanged,this,&MemoryView::adjustContent);
连接(horizontalScrollBar(),&QScrollBar::valueChanged,this,&MemoryView::adjustContent);
}
MemoryView::~MemoryView()
{
}
void MemoryViewer::init()
{
nBlockAddress=2;
mBytesPerLine=16;
pxWidth=fontMetrics().width(QChar('0'));
pxHeight=fontMetrics().height();
}
int memoryView::addressWidth()
{
返回(nBlockAddress*4+nBlockAddress-1)*pxWidth;
}
int memoryView::hexWidth()
{
返回(mBytesPerLine*3+1)*像素宽度;
}
int MemoryViewer::asciwidth()
{
返回(mBytesPerLine*2+1)*像素宽度;
}
QByteArray内存查看器::数据(qint64位置,qint64计数)
{
QByteArray缓冲区;
如果(位置>=尺寸)
返回缓冲区;
如果(计数<0)
计数=大小;
其他的
如果((位置+计数)>大小)
计数=大小-位置;
如果(ioDevice->open(QIODevice::ReadOnly)){
碘设备->寻道(pos);
缓冲区=碘设备->读取(计数);
ioDevice->close();
}
返回缓冲区;
}
无效内存视图::设置数据(常量QByteArray和ba)
{
缓冲区设置数据(ba);
设置数据(缓冲区);
}
bool MemoryViewer::setData(设备和设备)
{
ioDevice=&设备;
bool ok=ioDevice->open(QIODevice::ReadOnly);
如果(确定){
size=ioDevice->size();
ioDevice->close();
}
否则{
QBuffer*buf=新的QBuffer(本);
碘装置=buf;
}
init();
调整内容();
返回ok;
}
void MemoryViewer::resizeEvent(QResizeEvent*)
{
调整内容();
}
无效MemoryView::paintEvent(QPaintEvent*)
{
QPainter painter(viewport());
int offsetX=水平滚动条()->value();
int y=高度;
QString地址;
painter.setPen(viewport()->palete().color(qpalete::WindowText));
for(int row=0;row palete().color(Qpalete::AlternateBase));
x+=6*px宽度;
}
int-bPos=0;
对于(int row=0;rowsetRange(0,w-视口()->宽度());
水平滚动条()->setPageStep(视口()->宽度());
nRowsVisible=viewport()->height()/pxHeight;
int val=垂直滚动条()->value();
startPos=(qint64)val*mBytesPerLine;
endPos=startPos+nRowsVisible*mBytesPerLine-1;
int lineCount=大小/mBytesPerLine;
verticalScrollBar()->setRange(0,lineCount nRowsVisible);
垂直滚动条()->setPageStep(nRowsVisible);
如果(endPos>=大小){
endPos=尺寸-1;
}
dataVisible=数据(startPos、endPos startPos+mBytesPerLine+1);
dataHex=dataVisible.toHex();
viewport()->update();
}
实现的一个优点是