C++ 如何通过QT实现我自己的内存查看器
最近我正在为自己的硬件编写一个调试器。我想添加一个内存查看器小部件,比如eclipse、QtCreator或其他IDE。然而,我不知道该使用什么样的小部件。例如,tableWidget,是否有如下设置:C++ 如何通过QT实现我自己的内存查看器,c++,qt,qt5,C++,Qt,Qt5,最近我正在为自己的硬件编写一个调试器。我想添加一个内存查看器小部件,比如eclipse、QtCreator或其他IDE。然而,我不知道该使用什么样的小部件。例如,tableWidget,是否有如下设置: 最好的选择是创建一个自定义小部件,因为任务是私有的,并且没有一个小部件适合任务 为此,我们将从QAbstractScrollArea继承,从这个类继承QTableView、QListView、QListWidget和QTableWidget。其设计用于在QScrolla区域内显示数据。 此外,
最好的选择是创建一个自定义小部件,因为任务是私有的,并且没有一个小部件适合任务 为此,我们将从QAbstractScrollArea继承,从这个类继承QTableView、QListView、QListWidget和QTableWidget。其设计用于在QScrolla区域内显示数据。 此外,这个类告诉我们如何创建自定义类 继承QAbstractScrollArea时,需要执行以下操作:
- 通过设置滚动条的范围、值、页面步长和 跟踪他们的行动
- 在中绘制区域的内容 根据滚动条的值创建视口
- 处理事件 由viewportEvent()中的视口接收
- 显著地调整事件的大小。 使用viewport->update()来更新视口的内容 当所有绘制操作都在视口中进行时,更新()的
#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();
}
实现的一个优点是