Очень сложно оценить код, так как он размещен здесь.
Похоже, вы создали подкласс QWidget
, Form_temp
, используя Qt Designer, что означает, что у него есть некоторый дополнительный багаж времени разработки, который ему на самом деле не нужен.
Когда вы создаете свой экземпляр Form_temp
, вы не устанавливаете MainWindow
в качестве родительского элемента в конструкторе, поэтому я не совсем уверен, как ваш собственный виджет будет рисовать сам себя, поскольку он никогда не получает вызов show()
сама. Это также никогда не разрушается.
Необходимая проводка для использования слота и реализации также отсутствует, поэтому невозможно определить, является ли это проблемной областью в этой ситуации.
Тем не менее, у вас должна быть возможность достичь своей цели :) Я настоятельно рекомендую вам ознакомиться с примером Qt Analog Clock , поскольку он довольно хорошо демонстрирует, как реализовать свой собственный виджет.
Вы упоминаете, что хотите, чтобы ваш виджет обновлялся только при изменении данных, но вы неправильно понимаете, как работает платформа Qt. Вы хотите, чтобы ваш виджет рисовал сам, когда вы изменяете данные, но это не единственный раз, когда виджет должен рисовать сам, поэтому вы не должны пытаться ограничивать операцию рисования таким образом.
Поместите код в paintEvent()
, который закрасит весь виджет так, как вы хотите, чтобы он отображался на основе текущих данных. Фреймворк будет выполнять paintEvent()
при первом появлении виджета, когда он открывается после того, как ранее был скрыт другим окном, и во многих других ситуациях, над которыми вы не можете управлять.
Добавьте обычные методы (не требующие слотов), которые позволяют вам изменять базовые данные извне класса и обеспечивать, чтобы эти методы включали вызов update()
в конце их, чтобы они сигнализировали каркасу, что виджет следует перекрасить.
Если ваш виджет сложный и медленный для рисования, вы можете посмотреть на область, указанную в событии, переданном в paintEvent()
, чтобы ограничить ваш код рисования только той областью, которую нужно обновить.
UPDATE:
Ваш код близок. Я обрезал его до самого необходимого, чтобы продемонстрировать основы. Вы должны быть в состоянии уточнить это для ваших нужд.
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);
}