Доброго дня!
Ситуация: делаю прогу для построения графиков. Графики хочу, чтобы рисовались во вкладках (одна вкладка - один график). Не знаю, как заставить рисовальщик рисовать в нужной мне вкладке. Создаю, соответственно, в главном окне QTabWidget, в котором создаю вкладку. Сразу же после ее создания должен в ней отобразиться график. Как это сделать?
Если нет никакого подвоха, то, казалось бы, всё элементарно:
в paintEvent вкладки посмотреть, что должна отображать вкладка, и нарисовать это.
QMainWindow, сделай виджет, на котором будет рисоваться график и помести его в QTabWidget в качестве страницы
Аха, простой QWidget и поместить его туда. Такс, а как его соединить с вкладкой? Т.е. чтобы виджет tab отвечал своей странице?
QMainWindow, читай описание конструктора QWidget.
А как понять "чтобы виджет tab отвечал своей странице" ?
Имел ввиду, что когда нажимаем на вкладку (на прямоугольник с названием вверху), то на экране выводится именно тот график (или что-то другое), который соответствует данной вкладке))
Прочитай документацию по QTabWidget и всё поймёшь
Прочитал еще в первый раз, не разобрался тогда. Теперь понятно как размещать страницы во вкладках. Но пейнтер все равно не рисует. Говорит, что не активирован. Вот код:
tabWidget = new QTabWidget(centralwidget);
tabWidget->setObjectName(QString::fromUtf8("TabWidget"));
tabWidget->setGeometry(QRect(5, 30, width()-10, height()-85));
PageForGraphic = new QWidget;
PageForGraphic->setGeometry(QRect(5, 30, width()-10, height()-85));
void MainWindow::InTabs()
{
tab = new QWidget(); //Создаем вкладку.
PageForGraphic->setParent(tab); //Называем ее родителем.
tabWidget->addTab(tab, QString::fromLocal8Bit("Ãðàôèê %1").arg(tabWidget->count()+1)); //Добавляем ее на TabWidget.
tabWidget->setCurrentWidget(tab); //Подсвечивем.
}
void MainWindow::RunMNK(double *PointArrayX, double *PointArrayY, int N, int choise)
{
//Здесь написан некоторый код. Для его выполнения посылается сигнал из того диалогового окна.
ChooseGraphic(choise);
}
void MainWindow::ChooseGraphic(int choise)
{
C=choise;
update();
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(PageForGraphic);
switch(C)
{
case 1:
{
painter.setWindow(/*-LW*maxX-30, -LH*maxY-65,*/0,0, width(), height());
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(QColor(255, 0, 0), 7, Qt::SolidLine, Qt::RoundCap));
painter.drawPoints(PointArrayXY, M);
}
case 2:
{
//
}
case 3:
{
//
}
}
}
Сам пейнтэвент. В нем указываю, где рисовать, но он не рисует))Может, оно и не оно, но одна ошибка (даже 3) точно есть: в твоём лирическом о. нет break после каждого case.
вот это тоже сильно смущает
QPainter painter(PageForGraphic);
обычно тут
QPainter painter(this);
Зачем окну рисовать в другом окне ?
Эт по невнимательности. Исправил, но painter как не был активированным, так и не активирован... Странно, вот если написать QPainter painter(this);, то он все прекрасно рисует... Но только непосредственно в главном окне((
Ясно. И что тогда делать? Создать отдельный класс для моей PageForGraphic и уже в нем рисовать?
QMainWindow, ну, начнём с того, что каждая вкладка у тебя - в общем случае отдельный класс. По крайней мере - разные экземпляры точно.
То есть, у тебя есть набор вкладок (которые ты можешь включить в ТАБ или не включать)
QMyTabPage_name1;
QMyTabPage_name2;
QMyTabPage_name3;
...
На каждой вкладке свои контролы. А контролам пофиг, где они лежат - они выполняют/отображают то, что должны
И как это связано с paintevent?
А зачем с ним связывать ? Его вообще надо будет переопределить только в том самом самописном контроле, в котором будет график рисоваться.
А для работы с вкладками его трогать не нужно
А можно примерчик Туго доходит
QMainWindow, не совсем понимаю - пример чего?
Давай так: создай новый проект на основе диалога, добавь туда табконтрол, в него несколько вкладок.
Затем тебе нужен самописный (или какой там ты хотел применить) виджет. Его кидаешь на нужные вкладки.
И это всё. Остальное - детали реализации того виджета (в частности - рисование)
Проект прикрепи - где остановился скажи
[offtop]
Прикольная ситуация - класс QMainWindow задаёт вопросы про работу QWidget )
[/offtop]
Выкладываю непосредственно саму программу. Делать стал недавно, поэтому там мало чего еще написано. Все, что я показывал здесь находится в mainwindow.cpp. Вот ссылка на скачку: http://ifolder.ru/18745087. Если поможите, буду оч. благодарен Просто не возьму в толк, что писать-то надо?)
QMainWindow, тебе уже говорили на прогорге, рисовать можно "только" в событии paintEvent. Под сделай виджет для рисования подразумевалось не
new QWidget
а создание собственного класса-наследника от QWidget или другого, более подходящего. В обработчике paintEvent этого класса и рисуй.
Так я это уже спрашивал, вот:
Короче создал класс для виджета, в котором буду рисовать. Сделал .h и .cpp файлы соответственно. Объявил все необходимое, соединил виджет через сигналы с главным окном. В mainwindow.h (заголовочный файл Главного окна) вписал следующее:
#include "PaintWidget.h"
PaintWidget.h - собственно з.ф. моего виджета)) В приват секции создал указатель на на виджет: private:
PaintWidget *PageForGraphic;
чтобы его видели все слоты в главном окне. Соответственно в mainwindow.cpp написал команды, создающие вкладку и данный виджет(уже с графиком) в ней. В и все. Но он мне выдал ошибку: multiple types in one declaration. Че это такое? Никогда такой ошибки не получал ранее. Как избавиться - не знаю. Знаю, что если убрать из mainwindow.h надпись #include "PaintWidget.h", то ее не будет, но тогда не получится объявить мой виджет. Помогите плиз))напиши в самом начале файла "PaintWidget.h" строчку
#pragma once
Где-то ты дважды один и тотже файл включаешь.
QMainWindow, ты заголовочник защитил от множественного включения?
Странно, только что проверил еще раз - вроде нет... #ifndef и #endif Qt Creator пишет автоматически при создании заг. файла.
#ifndef PAINTWIDGET_H
#define PAINTWIDGET_H
#endif PAINTWIDGET_H
Так написано. Может скинуть файлы? Короче вот: http://ifolder.ru/18764953, чтобы дело быстрее двигалось.
QMainWindow, что ты там такое наколбасил, что сжатый проект не влазит в пост
Там примерно 700КБ, а в пост разрешено максимум 100КБ.
Так что там? Где я накосячил?
я не смог скачать - интер тупит сегодня, айфолдер, видимо, тоже
Может так: http://slil.ru/29530936.
wiz29, спасибо, но уже разобрались. Для каждого виджета - эксклюзивный paintEvent.))
QMainWindow, тоже не качается. Попробую вечером из дома
скачал. Так я и думал - папки debug и release не удалил ))
Нет проблем. Главное чтобы косяк убрать, а то работать дальше нельзя. И все мозгИ сломал, не знаю, что делать...
QMainWindow, времени у тебя, смотрю, вагон. Закомментируй всё любое, а потом открывай потихоньку, пока не заругается. Там и надо искать. Такой метод применим, когда голова уже квадратная, а компилятор всё ещё ругается ))
Только не забудь копию проекта сделать
Я понял, в чем косяк был - я был слепым!
Когда мы в заголовочном файле пишем наш класс, то после закрывающей фигурной скопки }, надо ставить ночку с запятой ; !!! А у меня ее не было, и оттуда косяк(подказали прогеры с прогорг). Зато теперь вместо одной ошибки - целых 6! И все связаны с тем, что методы и поля, которые я использую в paintEvent моего виджета (и в частности массив с точками, которые я хочу отобразить) не декларированы! (они объявлены в заголовочном файле главного окна, и мой виджет их не видит). Будем думать как исправить.
#include <QPainter>
PaintWidget::PaintWidget(QWidget* pParent,QPointF* pPointArrayXY)
:QWidget(pParent)
{
m_pPointArrayXY=pPointArrayXY;
}
PageForGraphic = new PaintWidget(this,PointArrayXY);
Спасибо! Все эти глупые ошибки выявил еще с самого начала (они не не от незнания языка, а от тупой невнимательности). Сделал через сигналы и слоты. В общем, теперь он работает, рисует, но вот другая проблема: когда я создаю несколько графиков (и соответственно столько же вкладок), то во всех вкладках отображается только один последний созданный график. Я так понимаю, это из-за того, что за все мои вкладки отвечает только одна переменная tab. Встает вопрос: как заставить прогу создавать переменные?
QMainWindow, ответ кроется в ООП: храни данные о графике в классе рисовальщика. Тогда данные будут автоматически свои в каждом графике. Можно также предусмотреть возможность рисовать не с внутренних данных, а через указатель с внешних
грабли №1 пройдены
Закономерный вопрос: что нужно делать?
QMainWindow, как что - я ж написал, что делать У меня бы это выглядело как-то так:
#include <vector>
QGraphWidget: public QWidget
{
...
public:
typedef std::vector<QGraphElement> td_graph;
private:
td_graph m_Data;//для внутренних данных
td_graph* m_pOuterData;//для внешних
bool m_bUseOuterData;//флаг - показывать внешние данные
public:
QGraphWidget(QWidget* parent):QWidget(parent)
{
m_pOuterData=0;
m_bUseOuterData=false;
}
...
}
Спешу поделиццо радостной новостью. Он зарисовал так, как надо! Только я сделал QList и без всяких тайпдефов.
QMainWindow, ну, typedef - это лишь для удобства )
У меня вопрос: когда я открываю вкладку с графиком, то painter ее снова рисует или мой виджет с графиком на нем просто сохраняется в памяти, и когда я ее открываю, то программа берет ее из памяти? Или мой вопрос не корректен, типа все зависит от реализации?))
когда ты открываешь вкладку, то вызывается обработчик paintEvent() этой вкладки и тех виджетов, что размещены на ней.
И, соответственно, исполняется код этого обработчика.
Что ты в нём делаешь известно только тебе.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)