2014-11-18 2 views
0

Я создаю программу, которая рисует цвета, а другой класс проверяет их и возвращает true, если они совпадают. Весь код которого находится в диалоговом окне. colQ - класс, который просто хранит значения RGB и другие вещи; мы будем использовать их для получения RGB.Crash on keyPressEvent

colDialog::colDialog(QWidget *parent) // etc.. 
{ 
    // initialization code 

    colQ.setColor(255, 0, 0); // red 
    r_ans = g_ans = b_ans = nullptr; 
} 

У меня тогда есть событие рисования, которое делает рисунок. r1 и br1 являются указателями на их соответствующие классы.

void Atn_QDialog::paintEvent(QPaintEvent *e) 
{ 
    QPainter painter(this); 

    r1 = new QRect(100, 100, 175, 400); 
    br1 = new QBrush(QColor(colQ.getR, colQ.getG, colQ.getB)); 
    painter.fillRect(*r1, *br1); 
    painter.drawRect(*r1); 

    // other color code 
} 

На данный момент у меня будет прямоугольник, нарисованный красным цветом. Теперь я хочу, чтобы пользователь нажал клавишу (например, 1), а затем colQ проверит, соответствует ли цвет, соответствующий цвету на прямоугольнике, на который нажата клавиша.

void colDialog::keyPressEvent(QKeyEvent *Ev) 
{ 
    if (Ev->key() == Qt::Key_1) 
    { 
     br1->color().getRgb(r_ans, g_ans, b_ans); 
     colQ.answer(*r_ans, *g_ans, *b_ans); 

     if (colQ.isCorrect()) 
       ui->resultlabel->setText("correct!"); 
     else ui->resultlabel->setText("wrong!"); 
    } 

    // other key presses here 
    QDialog::keyPressEvent(Ev); 
} 

Ошибка возникает, когда я нажимаю клавишу «1», где код до сих пор реализован. Прежде, нажатие клавиши отвечает нормально, но это не происходит, когда этот код запущен. Fyi, colQ не имеет кода Qt Q, и опечатать его код по-прежнему вызывает сбой моей программы. Что я делаю здесь, я хочу получить цвет, хранящийся в br типа QBrush *. Я передал указатели в getRgb (..), поскольку это было то, о чем просили. Код срабатывает эффективно на keyPressEvent (Ev); такие вещи, как ui-> resultlabel- ~> setText ("..."), не приводят к сбою программы при нажатии клавиши. Это происходит только с вышеназванными вызовами функций.

ответ

1

Ваша программа падает здесь:

br1->color().getRgb(r_ans, g_ans, b_ans); 

r_ans, g_ans и b_ans должны быть инициализированы и память должна быть выделена для этих указателей. QColor::getRgb не выделяет вам память, он просто меняет значения и из-за этого он выходит из строя с ошибкой сегментации/доступом.

Внутри конструктора выделить память для этих 3 указателей:

colDialog::colDialog(QWidget *parent) // etc.. 
{ 
    // initialization code 

    colQ.setColor(255, 0, 0); // red 
    r_ans = new int; 
    g_ans = new int; 
    b_ans = new int; 
} 

Если у вас есть nullptr и вы пытаетесь разыменовать него: int *p = nullptr; int x = *p; программа даст сбой. Это то, что происходит внутри QColor::getRgb: 3 указателя разыменовываются, чтобы изменить значения, на которые они указывают, и поэтому ваше приложение выходит из строя.

Также ужасно вы, что вы делаете:

r1 = new QRect(100, 100, 175, 400); 
br1 = new QBrush(QColor(colQ.getR, colQ.getG, colQ.getB)); 

внутри paintEvent. Даже если вы освобождаете память где-то в функции paintEvent, это плохая идея. Объявите r1 в стеке и инициализируйте его в конструкторе, здесь вам не нужны указатели. Также создайте br1 на стеке. Нет необходимости в указателях и распределении динамической памяти.

+0

Я инициализировал r_ans, g_ans и b_ans для nullptr в конструкторе. Разве этого недостаточно, чтобы код работал? – Poriferous

+0

@ Vormeph Нет, вам нужно выделить память для них, см. Мои правки. – Iuliu

+0

Сначала это не сработало, но я позже прекратил встроенную инициализацию указателей и перевел ответы на другую функцию. Спасибо за вашу помощь! – Poriferous