【发布时间】:2015-04-22 03:18:46
【问题描述】:
我正在开发一个说明shannon-fano-coding 的程序。我使用 QLabel 来显示构成编码的二叉树的图像(底部的第三个选项卡名为“Baum”)。我的问题是,每当我更新图像时,它的高度都会扩展 1px。
主窗口.ui:
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QLabel" name="treeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
mainwindow.cpp ctor:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
codec = new SFCodec(ui->inputField);
QWidget::showMaximized();
QImage temp(ui->treeView->width(), ui->treeView->height(), QImage::Format_ARGB32);
temp.fill(QColor(255,255,255));
ui->treeView->setPixmap(QPixmap::fromImage(temp));
ui->treeView->show();
}
mainwindow.cpp 函数调用:
ui->treeView->setPixmap(QPixmap::fromImage(codec->getTreeView(ui->treeView->width(), ui->treeView->height())));
SFCodec.cpp绘图函数:
QImage SFCodec::getTreeView(int width, int height)
{
qDebug() << width << " " << height;
int treeWidth = width-50, //the tree should have 25px spacing on each side
treeHeight = height-50,
max_step_x = treeWidth/4, //max step length (i.e. the first step big step from the root)
step_x = max_step_x, //the current step length in x-direction
step_y = 0,
depth = 0, //max depth of the tree
length = 0; //helper variable to calculate the depth
QPoint p1(treeWidth/2,5),p2(0,0); //Lines are drawn between two points. These are the two points...
QImage image(width, height, QImage::Format_ARGB32); //new image with the right dimensions
image.fill(QColor(255,255,255,255)); //filled in with white (NOTE: the format is ARGB so the first '255' is the alpha channel)
if(index.isEmpty()) //no input text -> no code -> no tree
return image;
QPainter painter(&image); //Qt device that does all the painting
painter.setPen(QPen(QColor(0,0,0))); //paints in black
painter.setBrush(QBrush(QColor(Qt::color0), Qt::NoBrush));
painter.setRenderHint(QPainter::Antialiasing); //activate antialiasing since performance isn't an issue
//calculate depth by finding the symbol with the longest code (each digit in the code is one level of depth)
std::for_each(index.begin(), index.end(),[&](Symbol sym)
{
length = sym.getCode().length();
if(length > depth)
depth = length;
});
//we have treeHeight many pixels and want to fill them with depth many levels. so the step length in y direction has to be this long:
step_y = treeHeight/depth;
//paint the path for each symbol
//note that we always start from the root so some lines are painted multiple times
//this could be prevented by a recursive call which would be less readable and
//(probably) not significantly faster.
std::for_each(index.begin(), index.end(),[&](Symbol sym)
{
p1 = QPoint(treeWidth/2,5); //reset to starting position
step_x = max_step_x; //and step length
QString temp = sym.getCode();
do{
if(temp.at(0) == '1')
p2 = p1 + QPoint(step_x,step_y);
else
p2 = p1 + QPoint(-step_x,step_y);
step_x = step_x/2;
painter.drawLine(p1,p2);
p1 = p2;
temp.remove(0,1);
}while(temp.size());
p1 = p1 + QPoint(-5,15);
painter.drawText(p1, sym.getSym());
});
painter.end();
return image;
}
我很确定这与布局有关,因为我的代码总是使用标签的 width() 和 height() 函数来获取值,而且我也不会改变任何东西。
我知道这里有数以千计的关于布局和调整大小的线程,我浏览了其中的不少,但没有一个小部件可以自行扩展或类似的东西。
如果您想为项目贡献任何东西(这是为了我大学的计算机科学讲座),请在相应的 github 页面上进行。我是一名电气工程师,所以我的编码自然不符合标准。
【问题讨论】: