Qt以编程方式在调整UI组件大小时崩溃

时间:2018-07-24 20:46:48

标签: c++ qt user-interface qt5

我正在尝试更改 mainwindow.cpp 中中央小部件中resizeEvent出现的标签的大小。我已将resizeTimer用于超时。 resizeEvent函数正确,因为它正确打印了窗口大小。我试图通过在DriverWindow中包含 ui_driverwindow.h 来将MainWindow的用户界面从MainWindow更改。


这是我的MainWindow代码段

void MainWindow::resizeEvent(QResizeEvent *event)
{
    resizeTimer->stop();

    //currentEvent = event;
    resizeTimer->start(RESIZE_TIMEOUT);

    QWidget::resizeEvent(event);    
    QSize window_size = this->size();
    int resize_ht = window_size.height();
    int resize_wt = window_size.width();

    cout << "Size: " << resize_wt << " x " << resize_ht << endl;

    QRect rect = this->geometry();
    int h = rect.height();
    int w = rect.width();
    rect.setHeight(h/3);
    rect.setWidth(w/3);

    Ui::DriverWindow* ui;
    //The line below is the problem, when commented program executes without resizing the label
    ui->label->setGeometry(rect);
}

其中mainWindow.cpp已通过以下方式初始化:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

和driverWindow.cpp像这样:

DriverWindow::DriverWindow(QWidget *parent) :
    QMainWindow(parent),
    uno(new Ui::DriverWindow)
    {
    ui->setupUi(this);

debug模式运行此程序时,我得到:

The inferior stopped because it received a signal from the operating
system.

Signal name : SIGSEGV Signal meaning : Segmentation fault

已解决:

已替换

Ui::DriverWindow* ui;
ui->label->setGeometry(rect);

使用

ui->DriverWindow::ui->label->setGeometry(rect);

3 个答案:

答案 0 :(得分:2)

  

我试图通过在MainWindow中包含ui_driverwindow.h来从MainWindow更改DriverWindow的用户界面。

您不能也不应。 ui是实现细节。没有人应该在所使用的课程之外看到它。

如果要更改某个标签DriverWindow的几何形状,则应公开一个可实现此目的的方法。并使用方法:

class DriverWindow : public ... {
  Q_OBJECT
  Ui::DriverWindow *ui;
  ...
public:
  void setLabelGeometry(const QRect &rect);
  ...
};

void DriverWindow::setLabelGeometry(const QRect &rect) {
  ui->label->setGeometry(rect);
}

然后,我们假设:

class MainWindow : public QMainWindow {
  Q_OBJECT
  Ui::MainWindow *ui;
  ...
   QTimer *resizeTimer;
protected:
  void resizeEvent(QResizeEvent *) override;
  ...
};

当您可以按值存储事物时,也不必要地沉迷于指针。因此,以上内容可以重写为:

#include "ui_driverwindow.h"
class DriverWindow : public ... {
  Q_OBJECT
  Ui::DriverWindow ui;
  ...
public:
  explicit DriverWindow(QWidget *parent = nullptr);
  void setLabelGeometry(const QRect &rect);
  ...
};

DriverWindow::DriverWindow(QWidget *parent) : ...(parent) {
  ui.setupUi(this);
}   

void DriverWindow::setLabelGeometry(const QRect &rect) {
  ui.label->setGeometry(rect);
}

#include "ui_mainwindow.h"
class MainWindow : public QMainWindow {
  Q_OBJECT
  Ui::MainWindow ui;
  ...
  QTimer resizeTimer{this};
protected:
  MainWindow(QWidget *parent = nullptr);
  void resizeEvent(QResizeEvent *) override;
  ...
};

也不必停止计时器以重新启动它-只需重新启动即可。 qDebug直接处理许多Qt类型。我还假设DriverWindow是中央窗口的类型(您在此提示)。因此:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
  ui.setupUi(this);
}

void MainWindow::resizeEvent(QResizeEvent *event) {
  resizeTimer.start(RESIZE_TIMEOUT);
  QMainWindow::resizeEvent(event);

  qDebug() << "Size:" << size();

  const QRect rect(pos.x(), pos.y(), width()/3, height()/3);
  qDebug() << "New rect:" << rect;  

  auto *central = qobject_cast<DriverWindow*>(centralWidget());
  Q_ASSERT(central);
  central->setLabelGeometry(rect);
}

答案 1 :(得分:1)

这里:

Ui::DriverWindow* ui;
//The line below is the problem, when commented program executes without resizing the label
ui->label->setGeometry(rect);

ui在这里是未初始化的本地指针变量。未定义的行为,崩溃是常见的,幸运的结果。您可能需要this-> ui或其他内容。

此外,打开并纠正编译器警告,编译器应警告您使用未初始化的变量。

答案 2 :(得分:0)

这是解决方案,而不是reset = () => { let {editorState} = this.state; editorState = clearEditorContent(editorState); this.setState({ editorState }); this.props.completeClear(); };,而是我使用的ui->label->setGeometry(rect);。我需要在DriverWindow中提及要访问的用户界面。