Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
0 / 0 / 0
Регистрация: 27.05.2015
Сообщений: 20

QWidget и его связь с QPainter

27.05.2015, 15:34. Показов 4341. Ответов 37
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.Возникла проблема при реализации поставленной цели.

Имеется программа при запуске которой появляется окно с виджетами(QLabel,QLineEdit,QPushButton,Q TextEdit)
в итоге в данном окне в поля lineEdit вводятся значения.после нажатия на кнопку (pushBatton) вызывается функция которая дальше работает с данными значениями и в конечном итоге выдает в поле(textEdit) вычисленные в программе значения.Сейчас требуется после поля textEdit создать еще виджет и чтобы при нажатии кнопки еще и в этот виджет выводился рисунок построенный с помощью QPainter. Пробовала просто для начала без своих значений вывести в мой виджет пример из книги:
C++ (Qt)
1
2
3
4
5
6
7
8
9
void GoDialog:: paintEvent(QPaintEvent *event)
{
    QRect r1(100, 200, 1100, 1600);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(QPen(Qt::black, 3, Qt:: DashDotLine, Qt::RoundCap));
        painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
        painter.drawEllipse(200, 80, 400, 240);
}
С this рисует прописанную фигуру в главном окне в том же месте где расположены мои лэйблы и прочие виджеты.

А если создаю виджет в котором хочу чтобы потом отображалась моя фигура и прописываю его название вместо this то фигура вообще не выводится.и поле остается пустым.
C++ (Qt)
1
2
3
4
5
6
7
8
9
canvas = new QWidget;
canvas->setMinimumSize(200,200);
mainLayout->addWidget(canvas);
 
{
...
QPainter painter(canvas);
...
}
В Qt новичок и не понимаю по каким причинам фигура не хочет выводиться в созданный в главном окне виджет.

И не понятно как сделать так чтобы вырисовывало фигуру только после нажатия кнопки да еще и используя посчитанные значения полученные в вызванной после нажатия кнопки функции .
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.05.2015, 15:34
Ответы с готовыми решениями:

Про QWidget и рисование на нём QPainter
В общем такие дела: Заранее просьба не ругать, с Qt работаю практически впервые, поэтому буду тупить много. Есть форма. На ней...

Как открыть QWidget из QWidget по нажатию кнопки
Здравствуйте! Подскажите как открыть по нажатию QPushButton еще один QWidget в нижеприведенном коде появляется окно и сразу уничтожается,...

Как связать QWidget* w = new QWidget(this) с файлом формы UI ?
Ну вопрос в сабже. Создал простую форму без класса. В коде применяется QGraphicsProxyWidget, у которого можно вытащить указатель на...

37
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.06.2015, 15:09
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Natalyyy Посмотреть сообщение
Тут вопрос был относительно того там ли я прописываю...
А мне откуда знать туда или не туда.. нужно видеть код.
1
0 / 0 / 0
Регистрация: 27.05.2015
Сообщений: 20
01.06.2015, 17:15  [ТС]
canvas.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef CANVAS_H
#define CANVAS_H
#include <qdialog.h>
#include <qpainter.h>
 
class Canvas : public QWidget
{
    Q_OBJECT
 
public:
    
    Canvas(QWidget *parent = 0);
    void paintEvent(QPaintEvent *event);
    bool canDrawShape;
 
};
 
#endif
canvas.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Canvas::Canvas(QWidget *parent)
    :QWidget(parent)
 
{
    canDrawShape=false;
}
 
void Canvas::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);
    if(canDrawShape)
    {
        QPainter painter(this);
        ...
        painter.draw...;
    }
}
goDialog.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#ifndef GODIALOG_H
#define GODIALOG_H
#include <qdialog.h>
#include <qpainter.h>
#include "canvas.h"
 
class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;
class QTextEdit;
class QHBoxLayout;
class QVBoxLayout;
 
class GoDialog  : public Canvas
{
    Q_OBJECT
 
public:
    GoDialog(QWidget *parent = 0);
    void paintEvent(QPaintEvent *e)
    {
        QWidget::paintEvent(e);
    }
 
private slots:
    void goClicked();
 
private:
 
    ...
 
    QPushButton *goButton;
 
    ...
    QHBoxLayout *hBox2;
    QVBoxLayout *mainLayout;
    
 
    ...
    
    Canvas *canvas;
 
    ...
 
#endif
goDialog.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
GoDialog::GoDialog(QWidget *parent):Canvas(parent)
{
    
    ...
    goButton = new QPushButton(tr("&GO!"));
 
    ...
 
    canvas = new Canvas();
    canvas->setMinimumSize(300,300);
 
    connect(goButton, SIGNAL(clicked()),
        this, SLOT(goClicked()));
 
    
 
 
    hBox2 = new QHBoxLayout;
    hBox2->addWidget(goButton);
    
    
    mainLayout = new QVBoxLayout;
    
    
    mainLayout->addLayout(hBox2);
        ...
    mainLayout->addWidget(canvas);
    
    
    
    
    setLayout(mainLayout);
    
    
    
}
 
 
 
void GoDialog::goClicked()
{
    
 
 
    //Вычисления
    canDrawShape=true;
        canvas->update();
    
}
main.cpp
C++ (Qt)
1
2
3
4
5
6
7
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    GoDialog *dialog = new GoDialog;    
    dialog->show();
    return app.exec();
}
Добавлено через 1 час 15 минут
В canvas->update canDrawShape почему то снова false становится...
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.06.2015, 17:22
Вероятно :
C++ (Qt)
1
2
3
4
5
void GoDialog::goClicked()
{
    canvas->canDrawShape= true; /*   canvas->  */
    canvas->update();    
}
1
0 / 0 / 0
Регистрация: 27.05.2015
Сообщений: 20
01.06.2015, 17:26  [ТС]
Спасибо огромное)))ты гений)
0
0 / 0 / 0
Регистрация: 27.05.2015
Сообщений: 20
02.06.2015, 17:32  [ТС]
А если необходимо чтобы мой рисунок обновлялся при изменении значений и повторном нажатии на кнопку то функция update не подойдет?просто как я поняла она и отвечает за перерисовку.но при нажатии на кнопку с новыми значениями почему то не изменяются мои фигуры...
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.06.2015, 17:45
Вызов update() вызывает paint() ( Но paint() может вызыватьсяи при других "событиях" )

Добавлено через 4 минуты
Цитата Сообщение от Natalyyy Посмотреть сообщение
А если необходимо чтобы мой рисунок обновлялся при изменении значений и повторном нажатии на кнопку то функция update не подойдет?
В принципе должно произойти, вопрос в том правильно ли вы это делаете.
1
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,341
02.06.2015, 21:45
Посмотрите здесь (Qt 4.8). Рисуется как раз по нажатию кнопки:
Миниатюры
QWidget и его связь с QPainter  
Вложения
Тип файла: zip sinusoida.zip (11.0 Кб, 6 просмотров)
1
0 / 0 / 0
Регистрация: 27.05.2015
Сообщений: 20
03.06.2015, 09:34  [ТС]
alexu_007, спасибо)Но у меня не график рисуется а фигуры и помимо них нужно еще вводить самой значения и выводить нужные расстояния.Так что думаю что мне этот вариант не подойдет. Проще разобраться с тем что уже имею.

Добавлено через 21 минуту
Avazart,

canvas.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Canvas : public QWidget
{
    Q_OBJECT
 
public:
    
    Canvas(QWidget *parent = 0);
    //QWidget *canvas;
    void paintEvent(QPaintEvent *event);
    bool canDrawShape;
    double G_x;
    double F_x;
    double H_x;
    double N_x;
    double G_z;
    double F_z;
    double H_z;
    double N_z;
 
};
 
#endif
Тут добавились переменные которым потом будут присваиваться значения расчетов.

canvas.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Canvas::Canvas(QWidget *parent)
    :QWidget(parent)
 
{
    canDrawShape=false;
    G_x=0.0;
    F_x=0.0;
    H_x=0.0;
    N_x=0.0;
    G_z=0.0;
    F_z=0.0;
    H_z=0.0;
    N_z=0.0;
}
 
void Canvas:: paintEvent(QPaintEvent *event)
{
 
    if(canDrawShape)
    {
 
        QPainter painter(this);
        painter.setWindow(-5,-5,10,10);
        static const QPointF points_center[4] = 
        {
            QPointF(-G_x, -G_z),
            QPointF(-F_x, -F_z),
            QPointF(F_x, -F_z),
            QPointF(G_x, -G_z)
        };
        ...
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(QPen(Qt::white, 0.01, Qt::SolidLine, Qt::RoundCap));
        painter.setBrush(QBrush(Qt::blue, Qt::SolidPattern));
        painter.drawPolygon(points_center, 4);
        ...
    }
}
Тут в конструкторе обнулила переменные свои. Ну и в рисовальщике соответственно уже они при построении участвуют.

goDialog.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
GoDialog::GoDialog(QWidget *parent):Canvas(parent)
{
        ...
 
 
    canvas = new Canvas(this);
    canvas->setMinimumSize(500,500);
 
 
    connect(goButton, SIGNAL(clicked()),
        this, SLOT(goClicked()));
 
 
 
    hBox2->addWidget(goButton);
    
 
    mainLayout = new QVBoxLayout;
    
 
    mainLayout->addLayout(hBox2);
    mainLayout->addWidget(canvas);
    
    
    
    
    setLayout(mainLayout);
 
    
}
 
 
 
 
void GoDialog::goClicked()
{
      for(...)
      {
    ...//тут расчеты в результате которых получаются G.x,F.x... и т.д.
        
        if(... )
        {
            ...
            
            canvas->G_x=G.x*10;
            canvas->F_x=F.x*10;
                    canvas->H_x=H.x*10;
                    canvas->N_x=N.x*10;
                    canvas->G_z=G.z*10;
                    canvas->F_z=F.z*10;
                    canvas->H_z=H.z*10;
                    canvas->N_z=N.z*10;
            canvas->canDrawShape=true;
            canvas->update();
            
            
            
        }
    }
    
}
А тут присвоила переменным моего виджета значения получаемые при расчетах.В других частях изменений не делала
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,341
03.06.2015, 09:38
Раз проще - конечно разбирайтесь. Но я бы всё же посоветовал посмотреть, как оно работает у других. Потому что принцип тот же:

График рисуется не сам по себе, а с помощью линий, для которых заранее готовятся координаты (следующая линия начинается с конца предыдущей). Весь этот массив данных
C++ (Qt)
1
QList<int>
используется методом рисования
C++ (Qt)
1
void Widget::paintEvent(QPaintEvent *event)
, а вызывается рисование программно с помощью
C++ (Qt)
1
this->repaint();
Нужны не линии, а фигуры - кто против? Меняете код в paintEvent, чтобы рисовал нужные вам фигуры, и ессно создаёте для них нужные фигурам координаты.
1
0 / 0 / 0
Регистрация: 27.05.2015
Сообщений: 20
03.06.2015, 11:09  [ТС]
Суть та же,и прописываю так же разве что update вместо repaint использовала,но перерисовывать с новыми значениями все равно не хочет((не могу понять в чем проблема(
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.06.2015, 11:25
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void GoDialog::goClicked()
{
      for(...)
      {
    ...//тут расчеты в результате которых получаются G.x,F.x... и т.д.   
        if(... )
        {
            ...
            
            canvas->G_x=G.x*10;
            canvas->F_x=F.x*10;
                    canvas->H_x=H.x*10;
                    canvas->N_x=N.x*10;
                    canvas->G_z=G.z*10;
                    canvas->F_z=F.z*10;
                    canvas->H_z=H.z*10;
                    canvas->N_z=N.z*10;
            canvas->canDrawShape=true;
            canvas->update();       
        }
    }
}
Ну так у тебя тут только последний расчет прорисует, т.е ты просто не заметишь смену картинок при итерации for
Если хочешь что были заметны изменения, то итерировать нужно например в таймере с интервалом.
1
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,341
03.06.2015, 11:25
Ну попробуйте вы repaint(); поставить, може перерисуется. Код в paintEvent всегда рисует одно и то же по данным (координатам), которые вы ему даёте. При нажатии кнопки меняете данные и вызываете repaint - картинка меняется.

Может вы ему всё время одни те же данные подсовываете - он и рисует то же, а впечатление что не перерисовывает вообще.

Вы вообще как то сразу всё приложение написать хотите, а чтобы сразу всё заработало - надо быть гуру. А потом не понимаете, где и что у вас не работает. Я когда писал "синусоиду" сперва точку на форме нарисовал, потом отрезок - чтобы понять сам принцип. Потом "заставил" отрезок двигаться по нажатию кнопки. И так далее, от простого к сложному.
1
0 / 0 / 0
Регистрация: 27.05.2015
Сообщений: 20
03.06.2015, 11:39  [ТС]
Avazart, да мне и нужен самый последний вариант при котором выполняется условие if)Проблема в другом.это нарисуется последний рисунок который удовлетворяет условию,а если допустим я изменю значение в одном из полей lineEdit то посчитаются уже другие значения и соответственно с моим условием должна другая картинка уже стать.если я по новой запускаю программу и изменяю до нажатия кнопки значения то рисуется последний вариант для условия для этих значений.Но я не хочу каждый раз по новой запускать программу для новых значений)

Добавлено через 4 минуты
alexu_007, с repaint тоже не чертит.пошагово проверяла меняются ли при изменении значений мои координаты.так вот при изменении значений координаты изменяются,но функция update не хочет обновлять картинку.
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,341
03.06.2015, 11:40
Есть такая штука, называется - отладка. Вставляете в начало файла

C++ (Qt)
1
#include <QMessageBox>
а в интересующее вас место:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void GoDialog::goClicked()
{ 
 
      QMessageBox msgBox;
 
 
      for(...)
      {
    ...//тут расчеты в результате которых получаются G.x,F.x... и т.д.   
        if(... )
        {
 
            msgBox.setText("любой текст");
            msgBox.exec();
      
            ...
            
            canvas->G_x=G.x*10;
            canvas->F_x=F.x*10;
                    canvas->H_x=H.x*10;
                    canvas->N_x=N.x*10;
                    canvas->G_z=G.z*10;
                    canvas->F_z=F.z*10;
                    canvas->H_z=H.z*10;
                    canvas->N_z=N.z*10;
            canvas->canDrawShape=true;
            canvas->update();       
        }
    }
}
Когда программа дойдёт до msgBox.exec(); на экран выскочит сообщение с текстом и надо будет нажать кнопку, чтобы продолжить. Сразу увидите, сколько раз выполняется то, что в фигурных скобках (каждый раз выскочит сообщение) и выполняется ли вообще - может у вас if(...) не проходит. Вместо текста можно вставить Qstring::number(число) и посмотреть свои координаты, что у вас там вычисляется. Ну просто же...
1
0 / 0 / 0
Регистрация: 27.05.2015
Сообщений: 20
03.06.2015, 11:47  [ТС]
alexu_007, у меня помимо картинки в программе еще и обновляется текст который я вывожу в поле textEdit))так вот после изменения значений в поле textEdit меняются значения полученные при расчетах в отличие от картинки)так что if точно проходит как надо)и если поставить пошагово циклы проверять то значения меняются)
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,341
03.06.2015, 11:55
Значит у вас проблемы с рисованием. Хотя я бы с рисования и начал, т.к. самое геморойное - сперва научился бы рисовать хоть что-то, а затем писать остальное.

У меня:

C++ (Qt)
1
this->repaint();
У вас:

C++ (Qt)
1
canvas->update();
Может не на ту канву рисует, и нужно указывать конкретно: this->canvas->update(); или там ui->canvas...
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.06.2015, 11:59
Цитата Сообщение от alexu_007 Посмотреть сообщение
Есть такая штука, называется - отладка. Вставляете в начало файла
Да есть такая штука отладка. )))

C++
1
2
3
#include <QDebug>
 
qDebug()<<"Отладка!!!" // Вывод в окно-лог отладки QtCreator
Добавлено через 1 минуту
Natalyyy, Может

C++
1
2
canvas->G_x= canvas->G_x*10;  // canvas->G_x *= 10;  
canvas->F_x= canvas->G_x*10;
Итд...
1
0 / 0 / 0
Регистрация: 27.05.2015
Сообщений: 20
03.06.2015, 12:03  [ТС]
Avazart, canvas->G_x=G.x*10;
тут же в правой части переменная структуры используется)не G_x, а G.x это переменная класса goDialog а G_x переменная класса Canvas.тогда если я пропишу как вы посоветовали то будут подставляться мои обнуленные значения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.06.2015, 12:03

Создание QWidget внутри QWidget
Есть окно QWidget, в котором есть кнопка. При нажатии на кнопку вызывается метод, который создает QWidget, как потомка 1-ого QWidget, и...

STAThreadAttribute и его связь с Main
Доброго дня всем, суть проблемы: Предыдущий проект по распаковке архивов был дописан, и заработал в приличном виде( спасибо за помощь с...

Дочерние окно и его связь с главным
Доброй ночи господа. Проблема такова есть диалоговое окно, в нём множество кнопок, но события на эти кнопки находятся на главном окне....

Использование метода Invoke() и его связь с потоками
Приветствую господа, мне нужно узнать поподробнее о конструкции Invoke, его само использование, и связь с потоками. Вообщем все про...

Вопрос про имеющийся сайт, его связь с биржей
Есть сайт. Контента 0. Пустой. Гуд дизайн и структура определена. Вопрос. Что если разместиться на бирже статей и продавать места под...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
38
Ответ Создать тему
Новые блоги и статьи
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru