Мне нужно проверить проект. Я запускаю Standalone-версию, запускаю compiler monitoring. Иду в свою IDE, пересобираю проект. Иду в Standalone, останавливаю мониторинг, потом файлы анализируются и выдается результат. Теперь я что-то меняю в проекте и хочу проверить изменения. Я снова запускаю compiler monitoring, иду в IDE, собираю проект (компилируются только измененные файлы), иду в Standalone, останавливаю мониторинг, потом файлы анализируются и выдается результат.
Автоперехват вызовов компилятора — волшебная фича. Скажите, а зачем там нужно выбирать между win32 и x64? Почему нельзя автоматически определить используемую архитектуру? Что будет, если выбрать неправильную? Еще немного раздражает, что выбор не запоминается и нужно при каждом запуске переключать на x64 вручную.
Еще было бы неплохо сделать возможность постоянного мониторинга вызовов. Сейчас приходится перед каждой сборкой запускать мониторинг, а потом его вручную завершать и ждать результатов. Если бы мониторинг и анализ велся постоянно, то можно было бы просто держать его в фоне, чтобы при возникновении ошибки он тут же о ней сообщил. Прогресс-бар в углу экрана тоже хотелось бы отключить.
Вроде бы очевидно, что 3, 4 и 5 — неправильные (сокращения оканчиваются точкой, для заглавной буквы тут нет причин), а остальные вполне понятны и приемлемы.
Меня сильно раздражает манера писать суммы денег в виде "$100 млн." Как это читать? Я это автоматически читаю как «долларов сто миллионов», и это режет глаз. Возможно, каким-то специалистам это кажется привычным, но вряд ли это удобно читать большинству людей. К сожалению, я не нашел в достаточно авторитетных источниках соответствующего правила, что затрудняет искоренение этого явления. Ализара, например, убедить я так и не смог, ссылка на gramota.ru его не убедила. Хабравчане, как вам больше нравится: "$100 млн." или «100 млн. $» («100 молн. долл.»)?
Каждый QObject принадлежит к какому-то потоку (по умолчанию это поток, в котором объект был создан, но можно переместить его в другой поток вручную). QObject::connect использует эту информацию.
В Qt существует три основных типа соединения: Direct, Queued, BlockingQueued. Если отправитель и получатель сигнала находятся в одном потоке, по умолчанию используется Direct, т.е. слот вызывается синхронно при вызове функции отправки сигнала. Если же они находятся в разных потоках, то по умолчанию используется Queued, в котором сигнал после создания просто кладется в очередь, а слот вызывается из event loop того потока, к которому принадлежит получатель. Это позволяет безопасно обмениваться данными с другими потоками, ведь сигналы — потокобезопасные функции, а слоты будут вызываться в том же потоке, что и другие методы объекта-получателя. При желании можно изменить поведение по умолчанию и указать тип соединения, который вы хотите использовать.
Хорошая книга должна быть идеально правильной. Особенно вредны ошибки в книгах для детей, ведь на этих текстах у них собирается представление о правилах, которое иногда перерастает в интуитивную грамотность. На представленных разворотах я нашел одну пропущенную запятую. Кроме того, кавычки и тире расставлены вопреки правилам русской типографики (нужно использовать «ёлочки» и длинное тире). Подобный уровень оформления недопустим для книг.
У издательств много минусов, но корректура у них обычно жесткая (по крайней мере, мне крайне редко попадаются ошибки в книгах, изданных крупными издательствами). Вам следует более серьезно отнестись к корректуре и верстке, если вы хотите быть не хуже.
1. Вы выбрали плохие названия для функций setPlot, setPlotGrid, setCurveParameters и setToolBar. В Qt принято начинать с set названия сеттеров, которые принимают новое значение свойства с соответствующим именем и устанавливают его. У вас эти функции не имеют аргументов, что вызывает недоумение. Можно было бы, например, назвать их addPlot, addPlotGrid, createCurve, addMyToolbar. Функция setToolBar настолько тривиальна, что лучше удалить ее, при этом уменьшится число строк и увеличится читаемость. Кстати, у вас в форме уже есть ui->mainToolBar, можно использовать ее, а не создавать еще одну.
2. У функции setStatusBar название особенно плохое, потому что функция QMainWindow::setStatusBar уже существует. Вы ее переопределили, и теперь она делает совсем не то, что раньше. Так нельзя делать, это чревато ошибками. Кроме того, реализация setStatusBar совершенно некорректна. В этой функции вы вызываете функцию statusBar(), если в Qt включена поддержка строки состояния. Функция statusBar() добавляет строку состояния, если ее еще нет. Однако во всех остальных местах вы просто вызываете statusBar(), не проверяя наличие поддержки строки состояния. Если убрать функцию setStatusBar и ее вызов, то ничего не изменится. Вообще говоря, поддержка строки состояния обычно в Qt всё-таки есть. Если же вы всё-таки хотите обрабатывать этот случай, то следует обернуть все вызовы statusBar в ifndef. А функцию setStatusBar и ее вызов всё-таки стоит удалить.
3. Вы снова используете setCentralWidget. Ваше право, но тогда нет смысла использовать Designer Form. Удалите форму из проекта, а из остальных файлов — упоминания о сгенерированном ui-классе. Ничего не изменится. Хотя нет, одна вещь изменится: удалится второй пустой тулбар, который вы всё равно не используете (видно на последнем скриншоте).
4. Нет смысла в переменных класса grid, symbol, magnifier, d_panner. Их можно сделать локальными. Некоторые другие переменные тоже можно сделать локальными, если немного перекомпоновать код. Чем локальнее, тем лучше.
5. Непонятно, зачем дублировать данные в pointArray и points и параллельно их менять. Можно убрать pointArray и использовать points вместо него.
В целом код переусложненный и плохо оформленный. Постарайтесь это исправить в следующих статьях. Кстати, исходники лучше выкладывать на github, а не в виде архива. Я бы вам сразу pull request сделал с готовыми правками.
Раз вы используете Designer Form Class, то логичнее и график на форму добавлять с помощью Qt Designer. Вроде бы даже есть специальный плагин, добавляющий возможность работы с классами Qwt в Qt Designer. Если с плагином возиться не хочется, можно просто добавить в форму обычный QWidget, а затем выбрать в контекстном меню Promote to и указать имя класса (QwtPlot) и заголовочный файл (qwt_plot.h). После этого график будет доступен через что-то вроде ui->plot. Плюс в том, что в форму можно добавить с помощью Qt Designer другие элементы (кнопочки и т.п.). В вашем варианте с setCentralWidget это проблематично.
Просто vxsw использовал количество возможных состояний мозга как аргумент. Я всего лишь попытался проиллюстрировать, что большое число состояний — это не редкость в нашем мире.
Нельзя утверждать, что мозг — самый сложный объект. Возьмем, например, Солнце. Разве оно проще? Атомов в нем больше, чем в мозге, так что и число возможных состояний у Солнца больше. Вся разница в том, что нам обычно нет дела до всех этих состояний. Например, мы не пытаемся точно предсказать излучение в каждой его точке в каждый момент времени на основе его внутреннего состояния. А это задача примерно такого же порядка, как отследить связь между физической работой мозга и сознанием человека. К сожалению, сейчас существует еще много явлений, которые нельзя полностью понять и проанализировать.
Еще было бы неплохо сделать возможность постоянного мониторинга вызовов. Сейчас приходится перед каждой сборкой запускать мониторинг, а потом его вручную завершать и ждать результатов. Если бы мониторинг и анализ велся постоянно, то можно было бы просто держать его в фоне, чтобы при возникновении ошибки он тут же о ней сообщил. Прогресс-бар в углу экрана тоже хотелось бы отключить.
В Qt существует три основных типа соединения: Direct, Queued, BlockingQueued. Если отправитель и получатель сигнала находятся в одном потоке, по умолчанию используется Direct, т.е. слот вызывается синхронно при вызове функции отправки сигнала. Если же они находятся в разных потоках, то по умолчанию используется Queued, в котором сигнал после создания просто кладется в очередь, а слот вызывается из event loop того потока, к которому принадлежит получатель. Это позволяет безопасно обмениваться данными с другими потоками, ведь сигналы — потокобезопасные функции, а слоты будут вызываться в том же потоке, что и другие методы объекта-получателя. При желании можно изменить поведение по умолчанию и указать тип соединения, который вы хотите использовать.
У издательств много минусов, но корректура у них обычно жесткая (по крайней мере, мне крайне редко попадаются ошибки в книгах, изданных крупными издательствами). Вам следует более серьезно отнестись к корректуре и верстке, если вы хотите быть не хуже.
2. У функции setStatusBar название особенно плохое, потому что функция QMainWindow::setStatusBar уже существует. Вы ее переопределили, и теперь она делает совсем не то, что раньше. Так нельзя делать, это чревато ошибками. Кроме того, реализация setStatusBar совершенно некорректна. В этой функции вы вызываете функцию statusBar(), если в Qt включена поддержка строки состояния. Функция statusBar() добавляет строку состояния, если ее еще нет. Однако во всех остальных местах вы просто вызываете statusBar(), не проверяя наличие поддержки строки состояния. Если убрать функцию setStatusBar и ее вызов, то ничего не изменится. Вообще говоря, поддержка строки состояния обычно в Qt всё-таки есть. Если же вы всё-таки хотите обрабатывать этот случай, то следует обернуть все вызовы statusBar в ifndef. А функцию setStatusBar и ее вызов всё-таки стоит удалить.
3. Вы снова используете setCentralWidget. Ваше право, но тогда нет смысла использовать Designer Form. Удалите форму из проекта, а из остальных файлов — упоминания о сгенерированном ui-классе. Ничего не изменится. Хотя нет, одна вещь изменится: удалится второй пустой тулбар, который вы всё равно не используете (видно на последнем скриншоте).
4. Нет смысла в переменных класса grid, symbol, magnifier, d_panner. Их можно сделать локальными. Некоторые другие переменные тоже можно сделать локальными, если немного перекомпоновать код. Чем локальнее, тем лучше.
5. Непонятно, зачем дублировать данные в pointArray и points и параллельно их менять. Можно убрать pointArray и использовать points вместо него.
В целом код переусложненный и плохо оформленный. Постарайтесь это исправить в следующих статьях. Кстати, исходники лучше выкладывать на github, а не в виде архива. Я бы вам сразу pull request сделал с готовыми правками.
Хабы с самыми успешными постами: cases (86), it_bigraphy (79), diy (76), easyelectronics (73), announcements (72), iconoskaz (72), i2p (72), asm (69), dura_lex (68), antikvariat (64), data_visualization (64), ebay (63), freelance (62), history (61), videocards (61).
Хабы с самыми заминусованными постами: joomla (2), cubrid (2), cakephp (5), bitrix (5), ms_access (6), sup_fabrik (6), sharepoint (6), azure (8), mssql (8), doctrine (8), derbyjs (9), bada_dev (9), crm (9), asterisk (10), begun (10).