1

親ウィジェット MainWindow で作成されたデータの配列に基づいて線を描画する Qwidget Form_temp を作成しました。私が直面している問題は、スロット send_data を介して MainWindow から Form_temp に送信したデータが、Form_temp の他の関数によって認識されないことです。(ペイント イベント)。

抜け穴がわかりません。データが Form_temp に到着することを検証するために、いくつかのデバッグ ポイントを追加しました。

ここにコードといくつかの説明があります。私は QTCreator でこれを行いました。助けてください。これに数日を費やし、先に進むことができません。

別の質問: paintEven は、ユーザーがマウスを動かしたり、別のウィジェットがビューを更新したりするたびに発生します (たとえば、時間を示すラベルがあります)。QPaintevens をフィルタリングしたいのですが、データが変更されたときに更新したいだけです。私がコード化したものよりもこれを行うためのより良い方法はありますか?

Qwidget : ヘッダー

    #ifndef FORM_TEMP_H
    #define FORM_TEMP_H
    #include <QWidget>
    #include <QDebug>

    namespace Ui { class Form_temp;   }

    class Form_temp : public QWidget        {
        Q_OBJECT
    public:
        QPainter *p;
        void paintEvent(QPaintEvent*);
        explicit Form_temp(QWidget *parent = 0);
        ~Form_temp();
        void send_data (int *parray, int asize);

        int array[48];
        int size;
        bool myupdate;

    private:
        Ui::Form_temp *ui;
    };

    #endif // FORM_TEMP_H

Qwidget : コア

#include "form_temp.h"
#include "ui_form_temp.h"
#include <cstdlib>
#include <QPainter>
#include <QDebug>

Form_temp::Form_temp(QWidget *parent) : QWidget(parent), ui(new Ui::Form_temp) {
    myupdate = false;
    ui->setupUi(this);
}
Form_temp::~Form_temp() { delete ui; }

void Form_temp::paintEvent(QPaintEvent*) {
    qDebug("Paintevent occurs");
    if (myupdate) {     // Event happen whenever I move the mouse,
                        // I only want an update when data changes.
      p = new QPainter(this);
      QPen pen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin);
      p->setPen(pen);
      p->setRenderHint(QPainter::Antialiasing,true);

      qDebug()<< "this size" <<size;        
      for (int i= 0; i< size; ++i) {
         qDebug()<< "array[i" <<i <<"]="<< array[i];
      }
      [...]
      p->drawLine(x1,y1,x2,y2);
      [...]
    }
myupdate = false;  
}

void Form_temp::send_data (int *parray, int asize){
    size = asize;
     for (int i= 0; i< asize; ++i) {array[i] = parray[i];}
     myupdate = true;  // make sure the event will update the drawing
     this->update();   // create a Qpaint Event

     qDebug()<< size;  // print the data so we know we are passing data correctly
     for (int i= 0; i< asize; ++i) {
        qDebug()<< "array[i" <<i <<"]="<< array[i];
     }
}

MainWindow: ヘッダー

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QtGui>
    #include "gpio.h"
    #include "form_temp.h"
    namespace Ui {
        class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
        Q_OBJECT

    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        //QPropertyAnimation *m_ani ;
        //QPropertyAnimation *m_ani2 ;
        Form_temp *temp_graph;
    [...]
    #endif // MAINWINDOW_H

MainWindow: コア

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

        // Start UI
        ui->setupUi(this);

        temp_graph = new Form_temp;
        startTimer(1000); // get timer event every sec.

   }

   void MainWindow::timerEvent(QTimerEvent *event)  {

      int data[]= {1,2,3};
      temp_graph->send_data(data, 3);
   }
  [...]

読んでくれてありがとう。セバスチャン。

4

1 に答える 1

0

ここに掲載されているコードを評価することは非常に困難です。

QWidgetQt Designerを使用してサブクラスを作成したようですForm_temp。つまり、実際には必要のない追加の設計時の手荷物があります。

のインスタンスを作成するとき、コンストラクターで親としてForm_temp設定MainWindowしていないため、カスタムウィジェットがそれ自体への呼び出しを受け取らないため、カスタムウィジェットがそれ自体をどのようにペイントするかはよくわかりませんshow()。また、破壊されることはありません。

スロットと実装を使用するために必要な配線も存在しないため、この状況でそれが問題のある領域であるかどうかを判断することはできません。

ただし、目標を達成することは可能です:) Qtアナログ時計の例を確認することを強くお勧めします。これは、独自のウィジェットを実装する方法を非常によく示しているためです。

データを変更したときにウィジェットが自動的に更新されるようにしたいが、Qtフレームワークがどのように動作するかを誤解しているとのことです。データを変更するときにウィジェットが自分自身をペイントするようにしたいのですが、ウィジェットが自分自身をペイントする必要があるのはこれだけではないので、そのようにペイント操作を制限しようとしないでください。

paintEvent()現在のデータに基づいてウィジェットを表示したいとおりにウィジェット全体をペイントするコードを挿入します。フレームワークはpaintEvent()、ウィジェットが最初に表示されたとき、以前に別のウィンドウによって隠された後に表示されたとき、および制御できない他の多くの状況で実行されます。

クラスの外部から基になるデータを変更できる通常のメソッド(スロットは不要)を追加し、それらのメソッドupdate()の最後にへの呼び出しが含まれていることを確認して、ウィジェットを再描画する必要があることをフレームワークに通知します。

ウィジェットが複雑でペイントに時間がかかる場合は、渡されたイベントで指定された領域を調べて、paintEvent()ペイントコードを更新が必要な領域のみに制限できます。

アップデート:

あなたのコードは近いです。基本を示すために、必要不可欠なものに切り詰めました。あなたはあなたのニーズのためにそれについて詳しく説明することができるはずです。

main.cpp

#include <QApplication>
#include "MainWindow.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow mainWindow;
    mainWindow.show();
    return app.exec();
}

MainWindow.h

#ifndef _MAINWINDOW_H
#define _MAINWINDOW_H

#include "Form_temp.h"

#include <QWidget>
#include <QTimer>

class MainWindow : public QWidget
{
    Q_OBJECT
public:
    MainWindow();
    virtual ~MainWindow();

private:
    Form_temp *temp_graph;   
    QTimer m_timer;

private slots:
    void slot_timeout();

};

#endif  /* _MAINWINDOW_H */

main.cpp

#include "MainWindow.h"

MainWindow::MainWindow():
    temp_graph(0),
    m_timer(this)
{
    temp_graph = new Form_temp(this);
    connect(&m_timer, SIGNAL(timeout()), this, SLOT(slot_timeout()));
    m_timer.start(1000);
}

MainWindow::~MainWindow()
{
}

void MainWindow::slot_timeout()
{
    int y = temp_graph->getY();

    y++;
    if(y > 10)
    {
        y = 0;
    }

    temp_graph->setY(y);
}

Form_temp.h

#ifndef _FORM_TEMP_H
#define _FORM_TEMP_H

#include <QWidget>

class Form_temp : public QWidget
{
    Q_OBJECT
public:
    Form_temp(QWidget *parent = 0);
    virtual ~Form_temp();

    void setY(const int newY);
    int  getY();

protected:
    void paintEvent(QPaintEvent *event);

private:
    int m_y;
};

#endif  /* _FORM_TEMP_H */

Form_temp.cpp

#include "Form_temp.h"
#include <iostream>
#include <QPaintEvent>
#include <QPainter>
#include <QPen>

using namespace std;

Form_temp::Form_temp(QWidget *parent) :
    QWidget(parent),
    m_y(1)
{
    cout << "Form_temp created." << endl;
}

void Form_temp::setY(const int newY)
{
    m_y = newY;
    update();
}

int Form_temp::getY()
{
    return m_y;
}

Form_temp::~Form_temp()
{
    cout << "Form_temp destroyed." << endl;
}

void Form_temp::paintEvent(QPaintEvent *event)
{
    cout << "Form_temp paintEvent." << endl;

    QPainter p(this);

    QPen pen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin);
    p.setPen(pen);
    p.setRenderHint(QPainter::Antialiasing, true);

    p.drawLine(0, m_y, width(), m_y);
}
于 2011-05-28T18:20:24.440 に答える