LINUX.ORG.RU

Сохрани данные в поле класса.

ox55ff ★★★★★
()
Ответ на: комментарий от XMs

Все достаточно просто. Есть поток в котором опрашиваются датчики. Состояние датчиков отображается на дисплее в виде квадратика с заливкой определенного цвета. Ну там красный цвет, датчик не исправный, зеленый исправен и т.д. Из потока передаю данные в виде массива. В массив загружаю данные состояния и адрес датчика. Вот этот массив нужно передать paintEvent.

Alex_Golubev
() автор топика
Ответ на: комментарий от Alex_Golubev

Самый простой случай — у тебя есть класс, где данные рисуются, и класс, получающий информацию от датчиков. Тут просто заводишь поле в первом классе, делаешь слот-сеттер, который принимает массив по сигналу второго класса, ну а рисование делаешь уже через член класса, не думая о втором классе.

Если делать более правильно, то у тебя должен быть отдельно класс, отображающий квадрат правильного цвета (типа, класс отображения датчика), отдельно класс, раскидывающий множество классов отображения датчика по какой-то сетке. В первом классе делаешь сеттер исправен/неисправен, принимать должен тип bool. Во втором принимаешь данные от датчиков и дёргаешь вышеупомянутый сеттер. По идее, тебе даже paintEvent() переопределять так не придётся, поскольку в качестве первого класса можно использовать какой-нибудь QLabel. Реализация первого класса будет выглядеть как-то так:

class SensorView: public QLabel
  {
	Q_OBJECT
	
	private:
		QColor m_brokenColor;
		QColor m_normalColor;
		QSize m_viewSize;
		bool m_isBroken;
		
	public:
		SensorView():
			m_brokenColor(Qt::GlobalColor::red),
			m_normalColor(Qt::GlobalColor::green),
			m_viewSize(32, 32);
		  { setBroken(false); }
		  
		void setBroken(bool broken);
		void setViewSize(const QSize &size);
  };
  
  
  
void SensorView::setBroken(bool broken)
  {
	m_isBroken = broken;
	
	QPixmap pm(m_viewSize);
	pm.fill(broken? m_brokenColor: m_normalColor);
	
	setPixmap(pm);
  }
  
  
  
void SensorView::setViewSize(const QSize &size)
  {
	m_viewSize = size;
	setBroken(m_isBroken);
  }

XMs ★★★★★
()
Ответ на: комментарий от Alex_Golubev

короче, шлешь сигнал с инфой о датчиках в класс, который дергает перерисовку, если необходимо и состояние изменилось, вот тех лейблов что показали выше.

deep-purple ★★★★★
()
Ответ на: комментарий от Alex_Golubev

По рабоче-крестьянски в сонном состоянии не разумею, сорян

XMs ★★★★★
()
Ответ на: комментарий от Alex_Golubev

Очень простое решение. Создаешь глобальный массив int. Старший бит - признак датчик исправен/нет, остальные 31 - его адрес. Когда нужно перерисовать, проходишь циклом по массиву.

Liz812
()
Ответ на: комментарий от Alex_Golubev

а сетка с квадратиками во вьюхе, которую дергает та, принимающая сигналы с обновлениями статусов, модель.

вообще можешь взять стандартную куть модель и стандартную табле вьюху - они уже сопряжены вместе и достаточно только обновить данные в модели (подписаться моделью на сигнал и обработать его в слоте), вьюха же сама обновит вид. с другой стороны это как посмотреть, подходит ли тебе такое решение по внешнему виду, и, возможно раскрашивать стандартную вьюху дороже, чем написать с нуля свои модель и вью.

deep-purple ★★★★★
()
Ответ на: комментарий от Liz812

глобальный массив int

Синглтон штоле? РЦ никто не отменял.

Когда нужно перерисовать

Да, когда?

циклом по массиву

А чтоб быстрее было — отправь на обработку об пень в желЕ.

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Синглтон - что это ? А чем не устраивает вот такой код это образец

[code] void MainWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this);

QFont font=painter.font() ;
font.setPointSize(18);
painter.setFont(QFont("monospace",12));

painter.drawText((352 + 32*0 + 5),(32 + 32*0 - 10),"1");
painter.drawText((352 + 32*1 + 5),(32 + 32*0 - 10),"2");
painter.drawText((352 + 32*2 + 5),(32 + 32*0 - 10),"3");
painter.drawText((352 + 32*3 + 5),(32 + 32*0 - 10),"4");
painter.drawText((352 + 32*4 + 5),(32 + 32*0 - 10),"5");
painter.drawText((352 + 32*5 + 5),(32 + 32*0 - 10),"6");
painter.drawText((352 + 32*6 + 5),(32 + 32*0 - 10),"7");
painter.drawText((352 + 32*7 + 5),(32 + 32*0 - 10),"8");
painter.drawText((352 + 32*8 + 5),(32 + 32*0 - 10),"9");


painter.drawText((352 + 32*0 - 35),(32 + 32*1 - 10),"1");
painter.drawText((352 + 32*0 - 35),(32 + 32*2 - 10),"2");
painter.drawText((352 + 32*0 - 35),(32 + 32*3 - 10),"3");
painter.drawText((352 + 32*0 - 35),(32 + 32*4 - 10),"4");
painter.drawText((352 + 32*0 - 35),(32 + 32*5 - 10),"5");
painter.drawText((352 + 32*0 - 35),(32 + 32*6 - 10),"6");
painter.drawText((352 + 32*0 - 35),(32 + 32*7 - 10),"7");
painter.drawText((352 + 32*0 - 35),(32 + 32*8 - 10),"8");
painter.drawText((352 + 32*0 - 35),(32 + 32*9 - 10),"9");
painter.drawText((352 + 32*0 - 35),(32 + 32*10 - 10),"10");
painter.drawText((352 + 32*0 - 35),(32 + 32*11 - 10),"11");
painter.drawText((352 + 32*0 - 35),(32 + 32*12 - 10),"12");
painter.drawText((352 + 32*0 - 35),(32 + 32*13 - 10),"13");
painter.drawText((352 + 32*0 - 35),(32 + 32*14 - 10),"14");


for(unsigned char y = 0; y < 14; y ++){

 for(unsigned char x = 0; x < 9; x++){

      painter.setBrush(QBrush(Qt::gray, Qt::SolidPattern));
      painter.drawRect((352 + 32*x), (32 + 32*y), 20, 20);
      painter.setBrush(QBrush(Qt::gray, Qt::SolidPattern));
      painter.drawRect((352 + 32*x + 5), (32 + 32*y + 5), 10, 10);
 }

}

} [/code]

Вызывается и рисует квадратики.

Alex_Golubev
() автор топика
Последнее исправление: Alex_Golubev (всего исправлений: 3)
Ответ на: комментарий от deep-purple

У меня таймер настроен на 5 секунд. Каждые 5 секунд происходит вызов paintEvent. Вот и все. Или вы что-то другое имеете в виду?

Alex_Golubev
() автор топика
Ответ на: комментарий от Alex_Golubev

Синглтон - что это ?

https://en.wikipedia.org/wiki/Singleton_pattern

А чем не устраивает вот такой код это образец

Вы не знаете, что такое циклы?

painter.drawText((352 + 32*0 + 5),(32 + 32*0 - 10),"1");
painter.drawText((352 + 32*1 + 5),(32 + 32*0 - 10),"2");
painter.drawText((352 + 32*2 + 5),(32 + 32*0 - 10),"3");
painter.drawText((352 + 32*3 + 5),(32 + 32*0 - 10),"4");
painter.drawText((352 + 32*4 + 5),(32 + 32*0 - 10),"5");
painter.drawText((352 + 32*5 + 5),(32 + 32*0 - 10),"6");
painter.drawText((352 + 32*6 + 5),(32 + 32*0 - 10),"7");
painter.drawText((352 + 32*7 + 5),(32 + 32*0 - 10),"8");
painter.drawText((352 + 32*8 + 5),(32 + 32*0 - 10),"9");


painter.drawText((352 + 32*0 - 35),(32 + 32*1 - 10),"1");
painter.drawText((352 + 32*0 - 35),(32 + 32*2 - 10),"2");
painter.drawText((352 + 32*0 - 35),(32 + 32*3 - 10),"3");
painter.drawText((352 + 32*0 - 35),(32 + 32*4 - 10),"4");
painter.drawText((352 + 32*0 - 35),(32 + 32*5 - 10),"5");
painter.drawText((352 + 32*0 - 35),(32 + 32*6 - 10),"6");
painter.drawText((352 + 32*0 - 35),(32 + 32*7 - 10),"7");
painter.drawText((352 + 32*0 - 35),(32 + 32*8 - 10),"8");
painter.drawText((352 + 32*0 - 35),(32 + 32*9 - 10),"9");
painter.drawText((352 + 32*0 - 35),(32 + 32*10 - 10),"10");
painter.drawText((352 + 32*0 - 35),(32 + 32*11 - 10),"11");
painter.drawText((352 + 32*0 - 35),(32 + 32*12 - 10),"12");
painter.drawText((352 + 32*0 - 35),(32 + 32*13 - 10),"13");
painter.drawText((352 + 32*0 - 35),(32 + 32*14 - 10),"14");

Отлично сворачивается в:

for (int i = 0; i < 9; ++i)
    painter.drawText((352 + 32*i + 5),(32 + 32*0 - 10), QString("%1").arg(i+1));

for (int i = 1; i <= 14; ++i)
    painter.drawText((352 + 32*0 - 35),(32 + 32*i - 10),QString("%1").arg(i));
EXL ★★★★★
()
Ответ на: комментарий от Alex_Golubev

а ты впиши в том методе: qDebug() << «ой»; и посмотри, раз в 5 сек или нет.

deep-purple ★★★★★
()
Ответ на: комментарий от Alex_Golubev

Тем, что ты хочешь передать какие-то данные в метод глобальной отрисовки, который в нормально спроектированной программе должен лишь рисовать.

EXL ★★★★★
()
Ответ на: комментарий от Alex_Golubev

Каждые 5 секунд происходит вызов paintEvent.

Как именно? Напрямую что ли? paintEvent() вызывается методом update() или repaint(), насколько я помню. Не нужно явно вызывать paint() или paintEvent(), поскольку эти методы являются перегруженными и фреймворк вызывает их автоматически, когда ты, например, сворачиваешь/разворачиваешь окно, меняешь фокус или просто проводишь курсором над канвасом.

EXL ★★★★★
()
Ответ на: комментарий от deep-purple

Причём тут кнопки и менюшки? У него вполне отчётливый вопрос:

Есть поток в котором опрашиваются датчики. Состояние датчиков отображается на дисплее в виде квадратика с заливкой определенного цвета. Ну там красный цвет, датчик не исправный, зеленый исправен

Лучшей задачи для Graphics View Framework и не придумаешь. Особенно если датчиков много. Завтра ему потребуется прикрепить какую-нибудь дополнительную информацию, которая показывается при наведении курсором на квадратик датчика и он будет два дня ковыряться в своей paintEvent-лапше.

EXL ★★★★★
()
Ответ на: комментарий от EXL

допинфа при наведении - тултип, сам же знаешь.

от пейневент лапши он так и так отойдет, не грузи его, видишь же на каком он уровне, а теперь еще и в сомнениях какой путь выбрать.

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

допинфа при наведении - тултип, сам же знаешь.

И как ты в глобальный paintEvent где он эти квадратики на канвасе рисует будешь его засовывать?

EXL ★★★★★
()
Ответ на: комментарий от deep-purple

См. стартовое сообщение этой темы.

EXL ★★★★★
()
Ответ на: комментарий от EXL

Это хорошая идея выводить информацию при наведении курсора на квадратик. Но у меня проблема квадратиков нужно 128 штук а дисплей и меня 640x480. И размер квадратика такой что пальцем не попадешь.Нужна экранная лупа или что-то типа того. Не знаю в общем.

Alex_Golubev
() автор топика
Ответ на: комментарий от Alex_Golubev

Тебя не поймешь. Спросил что вызывает paintEvent? Я ответила функция repaint. Она вызывает paintEvent сразу. Другие вызовы скорей приходят из очереди event loop. Кто их туда кладет, фиг его знает но ты их должен полюбому обрабатывать иначе виджет исказится.

Liz812
()
Ответ на: комментарий от deep-purple

Кстати, да, у вьюхи можно цвет на DisplayRole повесить, вообще удобно будет. Но тут уже вопрос, насколько вьюха подходит эстетически

XMs ★★★★★
()
Ответ на: комментарий от Alex_Golubev

Тем, что ты служебную функцию используешь не для того, для чего она предназначена

XMs ★★★★★
()
Ответ на: комментарий от Alex_Golubev

Потому что ты не понимаешь, как устроено рисование в Qt. Почитай документацию:

Each widget performs all painting operations from within its paintEvent() function. This is called whenever the widget needs to be redrawn, either as a result of some external change or when requested by the application.

И городить своё рисование в такой задаче, особенно после той простыни, на раз сворачиваемой в цикл — OCHE плохая затея. Воспользуйся готовыми виджетами или, как EXL посоветовал, используй Graphics Items

XMs ★★★★★
()
Ответ на: комментарий от EXL

EXL Как можно добавить «в ваш пример», второй вложенный квадрат в первый? У квадратов будут различные цвета.

Получается квадрат в квадрате.

Alex_Golubev
() автор топика
Последнее исправление: Alex_Golubev (всего исправлений: 1)
Ответ на: комментарий от Alex_Golubev

Эм. Если этот вложенный квадрат это просто нарисованный квадрат без сущности элемента, которым можно управлять, то, например, так:

QColor getColor(const bool state)
{
    return (state) ? QColor("#29AC3B") : QColor("#EB3838");
}

void Sensor::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QColor fillColor = getColor(ok), innerColor = getColor(!ok);
    painter->fillRect(boundingRect(), fillColor);
    painter->fillRect(boundingRect().intersected(QRectF(10, 10, 10, 10)), innerColor);

    QFont font("Monospace", 8);
    painter->setFont(font);
    painter->setPen(Qt::GlobalColor::white);
    painter->drawText(1, 10, QString("%1").arg(number + 1));
}
EXL ★★★★★
()
Ответ на: комментарий от EXL

Виноват. Управлять им надо. Получается если вписать квадрат в квадрат то получится внешняя рамка и внутри область в форме квадрата. Вот у рамки будет свой цвет а у внутреннего квадрата свой цвет. Управление цветами будет независимое.

Alex_Golubev
() автор топика
Ответ на: комментарий от Alex_Golubev

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

Если да, то в чём, собственно, проблема?

И что ты имеешь в виду под утверждением «управлять им надо»? Если только менять цвет – то зачем тебе этот квадратик как отдельный элемент? Я подразумевал под управлением, например, отдельное движение этого квадратика по полю или в пределах рамки и пр. сложные случаи.

EXL ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.