Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ не работает прорисовка в форме

Автор: voipp 26.10.2010, 21:00

создаю в основном файле в конструкторе тэбвиджет по имени tabWidget_2:

QTabWidget* tabWidget_2 = new QTabWidget(ui->tab);
    tabWidget_2->setObjectName(QString::fromUtf8("tabWidget_2"));
    tabWidget_2->setGeometry(QRect(500, 10, 391, 451));
    this->pictureU_T=new canvasForU_T();
    tabWidget_2->addTab(pictureU_T, QString::fromAscii("T_\\"));
    this->pictureU_X=new canvasForU_X();
    tabWidget_2->addTab(this->pictureU_X,QString::fromAscii("T_\\"));

ui->tab это виджет, который вставляется в еще один тэб под названием tabwidget(получается один тэб - "tabWidget_2" в другом тэбе - "tabWidget")
canvasForU_T() - класс унаследованный от QWidget(его-то я и хочу вставить в tabWidget_2).
Вот его описание:
#include "canvasforu_t.h"

canvasForU_T::canvasForU_T(QWidget* parent):QWidget(parent)
{
    paint=new QPainter(this);
}

void canvasForU_T::painEvent(QPaintEvent *){

    QColor color(Qt::blue);
    QPen pen(color);
    pen.setWidth(12);
    paint->setPen(pen);
    paint->drawLine(10,10,70,70);

}

canvasForU_T::~canvasForU_T(){
    delete paint;
}

canvasForU_X() это тоже самое, что и canvasForU_T().
Никаких линий не рисуется.Появляется ошибка:
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::begin: Paint device returned engine == 0, type: 1
QPaintDevice: Cannot destroy paint device that is being painted

Как ее исправить?

Автор: Алексей1153 26.10.2010, 21:43

вот так заработает

#include "canvasforu_t.h"

canvasForU_T::canvasForU_T(QWidget* parent):QWidget(parent)
{
  //  paint=new QPainter(this);
}

void canvasForU_T::painEvent(QPaintEvent *)
{
    QPainter paint(this)

    QColor color(Qt::blue);
    QPen pen(color);
    pen.setWidth(12);
    paint.setPen(pen);
    paint.drawLine(10,10,70,70);

}

canvasForU_T::~canvasForU_T()
{
  //  delete paint;
}

Автор: voipp 26.10.2010, 21:48

ошибок кроме удаления нет.Но линии всеранво не чертятся((.А откройте секрет- почему ошибок не стало?
Вот кстати деструктор из основногокласса:

MainWindow::~MainWindow()
{
   delete ui;
   delete this->pictureU_T,this->pictureU_X;
}

Автор: Алексей1153 26.10.2010, 21:50

voipp, а с моим вариантом попробовал ?

Автор: voipp 26.10.2010, 21:51

я с вашим вариантом и пробовал.Кстати я включил дебаггер(постаивл точки останова в пэйнтивенте в классе

canvasForU_T
) и он по ним не прошелся(((

Автор: Алексей1153 26.10.2010, 21:54

при чём тут деструктор MainWindow ? ))

а вот так попробуй, начертится чёрная линия ?

#include "canvasforu_t.h"
void canvasForU_T::painEvent(QPaintEvent *)
{
    QPainter paint(this)
    paint.drawLine(0,0,100,100);
}

Автор: voipp 26.10.2010, 21:57

не всеравно зараза не чертит

Автор: Алексей1153 26.10.2010, 21:58

Цитата(voipp @ 27.10.2010, 0:51) *
) и он по ним не прошелся(((


у тебя класс canvasForU_T вообще является наследником QWidget ?

Автор: voipp 26.10.2010, 21:59

Да:

class canvasForU_T : public QWidget

кстати у меня класс canvasFor_T canvasFor_X в разных файлах лежат(но всеранво они присоеденены)

Автор: Алексей1153 26.10.2010, 22:02

voipp, прицепи ка проект, а то ничего не понятно.

Автор: voipp 26.10.2010, 22:05


Раскрывающийся текст

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include "cmath"
#include <QString>
#include <QMessageBox>
#include "matrix.h"
#include "canvasforu_t.h"
#include "canvasforu_x.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);
    ui->tabWidget->setTabEnabled(1,false);
    ust(ui->doubleSpinBox_2->value());
    ui->doubleSpinBox->setValue(0.1);

    //------------------------------------------------------------------------------------
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(ymethod()));
    connect(ui->doubleSpinBox_2,SIGNAL(valueChanged(double)),this,SLOT(ust(double)));
    //connect(ui->pushButton_3,SIGNAL(clicked()),this,SLOT(paintY()));
    //connect(this,SIGNAL(SGNL()),this,SLOT(ust(ui->doubleSpinBox_2->value())));
    //------------------------------------------------------------------------------------

    emit SGNL();
    //ui->tableWidget->resize(441,381);
    //ui->widget->installEventFilter(new WindowFilter(ui->widget));
    QTabWidget* tabWidget_2 = new QTabWidget(ui->tab);
    tabWidget_2->setObjectName(QString::fromUtf8("tabWidget_2"));
    tabWidget_2->setGeometry(QRect(500, 10, 391, 451));
    this->pictureU_T=new canvasForU_T();
    tabWidget_2->addTab(pictureU_T, QString::fromAscii("T_\\"));
    this->pictureU_X=new canvasForU_X();
    tabWidget_2->addTab(this->pictureU_X,QString::fromAscii("T_\\"));

    //this->pictureU_X->setGeometry(0,ui->tab_3->height()/2.0+1.0,ui->tab_3->width(),ui->tab_3->height());


}
/*
void MainWindow::paintEventForWindow(){
    QPainter painter(ui->widget);
    QColor color(Qt::blue);
    QPen pen(color);
    pen.setWidth(12);
    painter.setPen(pen);
    painter.drawLine(70,10,70,10);
}


bool WindowFilter::eventFilter(QObject *obj, QEvent *event){
    if(event->type()==QEvent::Paint){
        ((MainWindow*)obj)->paintEventForWindow();
        return 1;
    }
    return 0;
}
*/

MainWindow::~MainWindow()
{
   delete ui;
   delete this->pictureU_T,this->pictureU_X;
}

void SGNL(){
};
/*
void MainWindow::paintY(){

    painter= new QPainter(ui->widget);
    QColor color(Qt::blue);
    QPen pen(color);
    pen.setWidth(12);
    painter->setPen(pen);
    painter->drawLine(70,10,70,10);


}

*/
void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void MainWindow::printY(){


    unsigned h=Ynet.getHeight(),w=Ynet.getWidth();
    QTableWidgetItem* item;

    tb= ui->tableWidget;
    tb->setRowCount(h);
    tb->setColumnCount(w);
   // for(unsigned i=0;i<tb->columnCount();i++)
    //tb->setColumnWidth(i,tb->rowHeight(0));//высота как у 1 клетки
    for(unsigned i=0;i<h;i++)
        for(unsigned j=0;j<w;j++){
            item= new QTableWidgetItem(QString::number(Ynet[i][j]-(1.0-exp((-1)*pow(M_PI,2)*(Ttop-i*Tstep)))*sin(M_PI*j*Xstep)/pow(M_PI,2)));
            tb->setItem(i,j,item);
        };

}


void MainWindow::ymethod(){

Xtop=1;
Ttop=ui->doubleSpinBox_3->value();
Xstep=ui->doubleSpinBox_2->value();
Tstep=ui->doubleSpinBox->value();
Xnumb=(unsigned)ceil(1.0+(Xtop- 0.0)/Xstep);
Tnumb=(unsigned)ceil(1.0+(Ttop- 0.0)/Tstep);
Ynet.setSize(0,0);
Ynet.setSize(Tnumb,Xnumb);//v nachale tablica zapolnena nulyami

unsigned h=Ynet.getHeight(),w=Ynet.getWidth();

/*
QMessageBox *message;
if(!pow(Xstep,2)){
    message = new QMessageBox(QMessageBox::NoIcon,"Title0","Text0",QMessageBox::Ok);
    message->exec();
    delete message;
}
*/
double a=Tstep/pow(Xstep,2);



for(int i=h-2;i>=0;i--)
    for(unsigned j=1;j<(w-1);j++){

        Ynet[i][j]=(double)(Ynet[i+1][j-1]*a+Ynet[i+1][j]*(1.0-2.0*a)+Ynet[i+1][j+1]*a + a*pow(Xstep,2)*sin(M_PI*j*Xstep));

    }
double u=Ynet[h-1][1];
this->printY();
};


void MainWindow::ust(double hvalue){
   ui->doubleSpinBox->setMaximum(hvalue*hvalue/2.0);//!!!
   ui->doubleSpinBox->setValue((double)(hvalue*hvalue/6.0));
};

void MainWindow::paintEvent(QPaintEvent*){
    painter= new QPainter(this);
    QColor color(Qt::blue);
    QPen pen(color);
    pen.setWidth(8);
    painter->setPen(pen);
    //this->pictureU_T->update();

}


Раскрывающийся текст
#include "canvasforu_t.h"

canvasForU_T::canvasForU_T(QWidget* parent):QWidget(parent)
{
   // paint=new QPainter(this);
}

void canvasForU_T::painEvent(QPaintEvent *){

    QPainter paint(this);

    paint.drawLine(0,0,170,170);

}

canvasForU_T::~canvasForU_T(){
   // delete paint;
}


Раскрывающийся текст

#ifndef CANVASFORU_T_H
#define CANVASFORU_T_H

#include <QWidget>
#include <QPainter>


class canvasForU_T : public QWidget
{
public:
    canvasForU_T(QWidget *parent = 0);
    ~canvasForU_T();
   // QPainter* paint;
protected:
    void painEvent(QPaintEvent*);
};

#endif // CANVASFORU_T_H



Раскрывающийся текст

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtGui/QTableWidget>
#include "matrix.h"
#include "canvasforu_t.h"
#include "canvasforu_x.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow {
    Q_OBJECT
    //friend class WindowFilter;
public:

    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QTableWidget *tb;
    float Xtop,Ttop;
    unsigned Xnumb,Tnumb;
    float Xstep,Tstep;
    CMatrix Ynet;
    QPainter *painter;


    canvasForU_T* pictureU_T;
    canvasForU_X* pictureU_X;

public slots:
    void ymethod();
    void printY();
    void ust(double hvalue);

signals:
    void SGNL();

protected:
    void changeEvent(QEvent *e);
    void paintEvent(QPaintEvent*);

public:
    Ui::MainWindow *ui;
};

/*
class WindowFilter: public QObject{
    Q_OBJECT
    //friend class MainWindow;
protected:
    virtual bool eventFilter(QObject*,QEvent*);
public:
    WindowFilter(QObject* pobj=0,const char* pszName=0):QObject((QObject*)pobj){};

};
*/

#endif // MAINWINDOW_H


Автор: Алексей1153 26.10.2010, 22:07

voipp, проект - это папка с файлами, желательно упакованная в архив ;)

Автор: voipp 26.10.2010, 22:08

:rolleyes:
http://&quot;%20<a%20href="http://ifolder.ru/19961840&quot;"%20target="_blank">http://ifolder.ru/19961840&quot;</a>

Автор: Алексей1153 26.10.2010, 22:08

а ещё - у тебя Q_OBJECT в классе canvasForU_T не указан

Автор: voipp 26.10.2010, 22:16

а развев это макрос обязателен? Ведь я не сипользую там слоты и сигналы?

Автор: Алексей1153 26.10.2010, 22:40

ну, с ним, по крайней мере, работает ))

а без них компилятор верещит на всю консоль красными сообщениями - обращай внимание

void paintEvent(QPaintEvent*);- у тебя опечатка , не было "t"

и ещё: читай всё же предупреждения в консоли!

mainwindow.cpp: In destructor 'virtual MainWindow::~MainWindow()': 
mainwindow.cpp:67: warning: right-hand operand of comma has no effect
mainwindow.cpp: In member function 'void MainWindow::ymethod()':
mainwindow.cpp:149: warning: unused variable 'u'


если u - это фигня, что она не использована (или ты забыл?) , то

delete this->pictureU_T,this->pictureU_X;

- это утечка памяти

Автор: voipp 26.10.2010, 22:42

извиняюсь, а где вы нашли опечатку?

Автор: Алексей1153 26.10.2010, 22:43

painEvent

этакое болевое сообщение :))

Автор: voipp 26.10.2010, 22:43

извиняюсь, а где вы нашли u ? может pictureU_T ?

Автор: Алексей1153 26.10.2010, 22:45

voipp, да я ничего не искал - мне компилятор сказал

double u=Ynet[h-1][1];



Автор: voipp 26.10.2010, 22:46

Спасибо добрый человек! Все работает!

Автор: Алексей1153 26.10.2010, 22:48

наздоровье! :)

Автор: voipp 26.10.2010, 22:54

Но ошибка QPaintDevice: Cannot destroy paint device that is being painted всеранво осталась

Автор: Алексей1153 26.10.2010, 23:03

вот так не будет

//это к делу не относится, просто подправил ))
MainWindow::~MainWindow()
{
   delete ui;
   delete pictureU_T,
   delete pictureU_X;
}


//а это оно самое
/*
void MainWindow::paintEvent(QPaintEvent*){
    painter= new QPainter(this);
    QColor color(Qt::blue);
    QPen pen(color);
    pen.setWidth(8);
    painter->setPen(pen);
    //this->pictureU_T->update();
}
*/
void MainWindow::paintEvent(QPaintEvent*)
{
    QPainter painter(this);
    QColor color(Qt::blue);
    QPen pen(color);
    pen.setWidth(8);
    painter.setPen(pen);
}

Автор: voipp 26.10.2010, 23:20

а можно тупой вопрос - почему именно так? какая разница?

Автор: Алексей1153 26.10.2010, 23:25

voipp, да нормальный вопрос, отчего ж тупой. Можно было оставить, как было, с одним условием -вернуть память в кучу

painter= new QPainter(this);
...
delete painter;


а я написал с созданием переменной на стеке - она удалится автоматом
QPainter painter(this);



Читать про управление памятью в C++ .

Автор: Гость_voipp_* 27.10.2010, 9:33

"Можно было оставить, как было, с одним условием -вернуть память в кучу" так я ведь в деструкторе удаляю painter!

Автор: voipp 27.10.2010, 9:45

#include "canvasforu_t.h"

canvasForU_T::canvasForU_T(QWidget* parent):QWidget(parent)
{
    paint=new QPainter(this);
}

void canvasForU_T::paintEvent(QPaintEvent *){

    //QPainter paint(this);

    paint->drawLine(0,0,170,170);

}

canvasForU_T::~canvasForU_T(){
    delete paint;
}

В данном коде я ведь в деструкторе удаляю paint.Почему всеравно вылезает ошибка
QPainter::begin: Paint device returned engine == 0, type: 1
К тому же не рисуются никакие линии.Ведь деструктор вызывается перед выходом из программы!
PS. Остальной код рабоатет нормально

Автор: Litkevich Yuriy 27.10.2010, 9:58

voipp, QPainter надо создавать там где он нужен. Т.е. в методе paintEvent.


Автор: voipp 27.10.2010, 10:18

Цитата(Litkevich Yuriy @ 27.10.2010, 10:58) *
voipp, QPainter надо создавать там где он нужен. Т.е. в методе paintEvent.

Я подумал, что зачем каждый раз выделять память под художника(QPainter).И тем более я не вижу причины ошибки!Вот что самое главное!

Автор: BRE 27.10.2010, 10:24

А особенно памяти никакой и не выделяется.
QPainter это класс-рисовальщик, который содержит методы для рисования на QPaintDevice (которыми являются всякие QImage/QPixmap и конечно же QWidget).
Сам QPainter никаких тяжелых буферов не содержит.

Автор: Алексей1153 27.10.2010, 11:17

voipp, это не просто память под художника, это создание нового контекста графического устройства

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)