我在初始化与构造函数不同的成员类上的指针时有一个关于qt的怪异(至少对我来说是意外的)行为(崩溃)的问题。我附上我的代码的一部分:
在mainwindow.h中:
class MainWindow : public QMainWindow
{
...
private:
QPixmap *qpm_s1_yaw;
QPainter *s1_yaw_painter;
...
}
在mainwindow.cpp中:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
...
initGraph(qpm_s1_yaw, s1_yaw_painter, ui->YAW1);
...
}
void MainWindow::initGraph(QPixmap *map, QPainter *painter, QLabel *label)
{
map = new QPixmap(label->size());
map->fill(Qt::white);
painter = new QPainter(map);
... doing some stuff ...
label->setPixmap(*map); // ++(Remember this LINE)++
}
这确实有效,但是当我评论这一行时:
label->setPixmap(*map)
而是通过编写以下命令在构造函数(MainWindow :: MainWindow)中设置Pixmap:
ui->YAW1->setPixmap(*qpm_s1_yaw)
我遇到了细分错误。
有人可以解释这是怎么回事吗?为了使其工作,我必须初始化构造函数中的所有指针(并在类成员initGraph中注释这些行),如下所示:
qpm_s1_yaw = new QPixmap(ui->YAW1->size());
s1_yaw_painter = new QPainter(qpm_s1_yaw);
initGraph(qpm_s1_yaw, s1_yaw_painter, ui->YAW1);
ui->YAW1->setPixmap(*qpm_s1_yaw);
谢谢
最佳答案
这是对C ++的工作方式的琐碎误解,与Qt无关。
您的代码由您决定:您同样可以编写:initGraph(0, 0, ui->YAW1)
。您正在初始化局部变量,而不是类成员。您作为前两个参数传递的值没有任何用处。
完全没有必要通过指针来握住像素图和绘画工具。按值保存像素图,并且仅在绘画时实例化画家。
当您未在其上绘画时将画家保持在像素图上可能会导致在消耗(读取)像素图时制作不必要的像素图副本:具有活跃画家的像素图被视为“脏”。
然后,您应该做的是按值保存像素图,然后可以从initGraph
返回新值-这将initGraph
与存储像素图的周围类的详细信息分离。 initGraph
的用户可以选择不存储像素图,例如查询标签本身。
class MainWindow : public QMainWindow
{
Ui::MainWindow ui; // hold by value
...
QPixmap qpm_s1_yaw; // hold by value
QPixmap initGraph(QLabel *label) {
QPixmap pixmap{label->size()};
pixmap.fill(Qt::white);
QPainter painter{&pixmap};
//... doing some stuff ...
label->setPixmap(pixmap);
return pixmap;
}
public:
explicit MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
ui.setupUi(this);
gpm_s1_yaw = initGraph(ui.YAW1);
}
};