2013-08-26 38 views
1

我正在嘗試將一個窗口小部件添加到佈局中。QT C++ - 如何引用另一個類中的窗口小部件

該小部件完全在UI中處於另一個類中。通常我會做一個指向其他類(沒有UI,帶有小部件)的指針,這將是InkSpot *ink(類名是InkSpot),那麼我會說ui->paintAreaLayout->addWidget(ink->widget);,但那條線會導致應用程序崩潰,如果我刪除它並添加不引用該類的東西,那麼它不會崩潰。

我會提供大部分代碼,以便您可以更好地瞭解我正在嘗試執行的操作。測試按鈕是在所述第一碼塊的底部也就是一個問題:

inkpuppet.cpp

#include "inkpuppet.h" 
#include "ui_inkpuppet.h" 
#include "newdialog.h" 
#include "inkspot.h" 

#include <Qt> 
#include <QtCore> 
#include <QtGui> 
#include <QtWidgets> 
#include <QDialog> 
#include <QMainWindow> 


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

    //connect the frame range boxes to the timeslider 
    connect(ui->lowerFrameBox, SIGNAL(valueChanged(int)), this, SLOT(setMinimum(int))); 
    connect(ui->upperFrameBox, SIGNAL(valueChanged(int)), this, SLOT(setMaximum(int))); 

    //connect the menu items 
    connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(actionNew())); 

    //connect test 
    connect(ui->testButton, SIGNAL(clicked()), this, SLOT(testButton())); 
} 

InkPuppet::~InkPuppet() 
{ 
    delete ui; 
} 

void InkPuppet::setMinimum(int value) 
{ 
    ui->timeSlider->setMinimum(value); 
} 

void InkPuppet::setMaximum(int value) 
{ 
    ui->timeSlider->setMaximum(value); 
} 

void InkPuppet::actionNew() 
{ 
    NewDialog *dialog = new NewDialog; 
    dialog->setModal(true); 
    dialog->show(); 
} 

void InkPuppet::testButton() 
{ 
    ui->testButton->setText("working"); 
    //ui->paintAreaLayout->addWidget(ink->label); 
    //qDebug() << ui->testButton; 
    ui->paintAreaLayout->addWidget(ink->widget); 
} 

inkpuppet.h

#ifndef INKPUPPET_H 
#define INKPUPPET_H 

#include "inkspot.h" 

#include <QMainWindow> 

namespace Ui { 
class InkPuppet; 
} 

class InkPuppet : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit InkPuppet(QWidget *parent = 0); 
    ~InkPuppet(); 
    InkSpot *ink; 

private slots: 
    void setMinimum(int value); 
    void setMaximum(int value); 
    void actionNew(); 
    void testButton(); 

public: 
    Ui::InkPuppet *ui; 
}; 

#endif // INKPUPPET_H 

inkspot.cpp

#include "inkspot.h" 
#include "inkpuppet.h" 
#include "ui_inkpuppet.h" 

#include <QtCore> 
#include <QtGui> 
#include <QWidget> 
#include <QPainter> 
#include <QPaintEvent> 


void InkSpot::paintEvent(QPaintEvent *event) 
{ 
    QWidget *widget = new QWidget(); 
    widget->setFixedSize(100, 150); 
    QLabel *label = new QLabel(); 
    label->setText("test"); 
    widget->layout()->addWidget(label); 
    //InkPuppet.ui->paintAreaLayout->addWidget(widget); 

    QFile *brushInput; //takes raw 8 bit grayscale image, 8 bit values only 
    char *brushProto; 
    uchar *brushData; 

    brushInput = new QFile("x:\\Development\\InkPuppet\\brush.raw"); //open the raw file 
    brushInput->open(QIODevice::ReadOnly); 
    QDataStream in; 
    in.setDevice(brushInput); 
    int size = brushInput->size(); //set size to length of raw file 

    brushProto = new char[size]; 
    in.readRawData(brushProto, size); //read file into prototype 
    brushData = new uchar[size]; 

    for(int i = 0; i < size; ++i) 
    { 
     brushData[i] = (uchar)brushProto[i]; //copy char to uchar array 
    } 

    QImage test(brushData, 128, 128, QImage::Format_Indexed8); 
    QImage test2(128, 128, QImage::Format_ARGB32); 

    QVector<QRgb> vectorColors(256); //create color table 
    for(int c = 0; c < 256; c++) 
    { 
     vectorColors[c] = qRgb(c, c, c); 
    } 

    test.setColorTable(vectorColors); 

    for(int iX = 0; iX < 100; ++iX) 
    { 
     for(int iY = 0; iY < 100; ++iY) 
     { 
      test2.setPixel(iX, iY, qRgba(255 - (qrand() % 100), 0 + (qrand() % 100), 0 + (qrand() % 100), qAbs((int)test.pixel(iX, iY)-255))); 
     } 
    } 

    //final conversion for stencil and color brush 
    QPixmap testPixmap = QPixmap::fromImage(test2); 
    QPixmap testPixmap2 = QPixmap::fromImage(test); 

    QPainter painter(this); 

    painter.drawPixmap(150, 50, 100, 100, testPixmap); 
    painter.drawPixmap(50, 50, 100, 100, testPixmap2); 

    delete[] brushProto; 
    delete[] brushData; 
    delete brushInput; 
} 

inkspot.h

#ifndef INKSPOT_H 
#define INKSPOT_H 

#include <QObject> 
#include <QWidget> 
#include <QPainter> 
#include <QPaintEvent> 
#include <QLabel> 

namespace Ui { 
class InkSpot; 
} 

class InkSpot : public QWidget 
{ 
    Q_OBJECT 
public: 
    explicit InkSpot(QWidget *parent = 0); 
    ~InkSpot(); 
    void draw(QPainter *painter); 
    QWidget *widget; 
    QLabel *label; 
signals: 

public slots: 

protected: 
    void paintEvent(QPaintEvent *event); 

private: 
    Ui::InkSpot *ui; 

}; 

#endif // INKSPOT_H 
+0

與您引用任何其他類的任何其他對象成員的方式相同。 – dtech

回答

5

正如我想,你的錯誤是在另一個地方 如果您使用指針 - 檢查他們,如果他們每次使用的時間是不相等的NULL

我還沒有發現的ink初始化請檢查它

另外,不時清理你的版本 - 它可以防止一些錯誤。

+0

'InkSpot * ink;'在頭文件中?我經常清理構建。 – Vii

+0

你確定你的'墨水'已經初始化了嗎?例如,你可以在'InkPuppet'構造函數中初始化它,例如'ink = new InkSpot(this);' – troyane

0

這可能很愚蠢,但是如果將包含小部件的頭添加到UI類呢? 或者(重新)在UI中定義小部件,以便您可以使用它?

嘗試將標題(包含小部件的定義)添加到您的UI類中,以便UI知道該小部件。 定義是你定義元素和功能的地方(你放在標題中的東西

或者將定義添加到UI的頭文件中,如果你不需要頭的其餘元素,但第一個選項。會更好

+0

對不起,我對C++還很陌生,如何重新定義UI中的小部件? – Vii

+0

我編輯了我的答案,現在清楚了嗎? 重新定義我的意思是將聲明添加到您的UI的頭文件。 –

+0

我不知道如何將聲明添加到頭文件中,或者更具體地說是什麼意思。我已經在外部類中定義了小部件,爲什麼我需要再次定義它?它已經存在了,如果我在ui頭文件中聲明它,那麼我會碰到嘗試從原始類訪問它的完全相同的問題。 – Vii

相關問題