最近我正在爲自己的硬件編寫調試器。我想添加一個像eclipse或qt創建者或其他IDE的內存查看器小部件。但是,我不知道使用什麼樣的小部件。例如,tableWidget,有沒有一些設置,使其像這樣:怎樣才能實現我自己的內存查看器QT
0
A
回答
2
最好的辦法是創建一個自定義窗口小部件,因爲任務是私人的,沒有部件被容納到任務。
爲此我們將繼承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();
}
一種ADVA實施的缺點是您不必直接加載所有字節,因爲您可以傳遞一個從QIODevice
繼承的對象,如QFile
,並在視圖需要時通過消除內存開銷來讀取數據。此外,您可以通過一個QByteArray
在下面link,你會發現一個例子
+0
我真的很感謝你的幫助。超越我的話〜 –
相關問題
- 1. 我怎樣才能在QT
- 2. 我怎樣才能從Qt
- 3. 在java中,我怎樣才能讓Amazon EC2實例看到自己的標籤?
- 4. 我怎樣才能實現這與jQuery?
- 5. 我怎樣才能實現推宏?
- 6. 我怎樣才能讓自己的懶惰迭代器?
- 7. 我怎樣才能把這個自定義Linq查詢查看?
- 8. 我怎樣才能實現這個圖像效果iOS(看圖)
- 9. 我怎樣才能在QTreeWidget(Qt)
- 10. PHP - 我怎樣才能做我自己的人工驗證?
- 11. 我怎樣才能LD_PRELOAD我自己編譯的庫?
- 12. 我怎樣才能讓我的va_list參數重複自己?
- 13. Glyphicons如何工作?我怎樣才能製作我自己的?
- 14. MVC:我怎樣才能註冊控制器查看事件(C#)?
- 15. 我怎樣才能看到sdf文件
- 16. 我怎樣才能看到MSIL代碼
- 17. 我怎樣才能看到每一行?
- 18. 我怎樣才能讓自己的過渡更順利?
- 19. 我怎樣才能做自己的增量值在mysql
- 20. 我怎樣才能
- 21. 我怎樣才能
- 22. 我怎樣才能
- 23. 我怎樣才能
- 24. 我怎樣才能讓分行跟蹤自己?
- 25. 我怎樣才能解密此,所以我可以查看它
- 26. Symfony的1.4 - 我怎樣才能查詢
- 27. 我怎樣才能查詢URI從內部存儲器中的歌曲
- 28. 我怎樣才能控制器功能
- 29. 我怎樣才能使按鈕出現
- 30. 怎樣才能實現自定義種子的Rakefile
什麼是你的問題,你想獲得第一或第二圖像? – eyllanesc
兩個問題:1:得到第一個圖像; 2我已經實現了一個像第二個圖像的窗口,但我不知道如何改變文本的顏色,如第二個圖像 –
我建議問一個部分,因爲這些問題是獨立的。 – eyllanesc