我在初始化与构造函数不同的成员类上的指针时有一个关于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);
  }
};

09-05 23:25