我创建了一个Qwidget,Form_temp,它根据在父窗口小部件MainWindow中创建的数据数组绘制线条。我面临的问题是我通过插槽send_data从MainWindow发送到Form_temp的数据不会被Form_temp中的其他函数看到。 (的paintEvent)。
我无法弄清楚循环孔。我添加了几个Debug点来验证数据是否到达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);
}
[...]
感谢阅读。塞巴斯蒂安。
答案 0 :(得分:0)
在此处发布的代码评估代码非常困难。
看起来您使用Qt Designer创建了QWidget
子类Form_temp
,这意味着它有一些它并不真正需要的额外设计时间行李。
当您创建Form_temp
的实例时,您没有将MainWindow
设置为构造函数中的父项,因此我不太确定您的自定义窗口小部件将如何绘制自身,因为它从不接到show()
本身的电话。它也永远不会被破坏。
使用插槽和实现所需的布线也不存在,因此在这种情况下无法确定这是否是一个问题区域。
你应该可以实现你的目标但是:)我强烈建议你查看Qt Analog Clock Example,因为这很好地展示了如何实现你自己的小部件。
您提到您只需要在更改数据时更新自己的小部件,但是您误解了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);
}