Как стать автором
Обновить
33
0
Sam Protsenko @skb7

Пользователь

Отправить сообщение
Для владельцев Arduino Duemilanove: чтобы скомпилированный hex-файл залился в контроллер через AVRDude, необходимо в его настройках установить частоту передачи данных 57600 bod (в Eclipse — пункт меню Window -> Preferences -> AVR -> AVR Dude, выбрать свою конфигурацию и нажать Edit, в поле ввода «Override default baudrate» установить значение 57600). С частотой, указанной в статье, возникала ошибка доступа к контроллеру (и при попытке заливки прошивки, и при попытке считать тип контроллера и кварца).

Также маленькое дополнение — чтобы не подсвечивалось предупреждение на extern «C» — нужно в самом начале создавать не проект C, а проект C++, и все настройки, которые в статье описаны для компилятора C, устанавливать также и для компилятора C++.
Еще добавлю, что для воспроизведения в Guitar Pro 6, мне понадобилось установить pulseaudio, а для воспроизведения без RSE — использовать qsynth со звуковым шрифтом 8MBGMSFX.SF2. Установить RSE можно поставляемой с Guitar Pro утилитой GPBankInstaller.
Долго долбался с установкой на Debian Sid amd64, в ходе чего родился скрипт, которым я и хотел бы поделиться.
— скрипт положить в каталог с deb-пакетом Guitar Pro 6
— назвать его install_gp6_amd64.sh
— сделать chmod +x install_gp6_amd64.sh
— запускать скрипт командой ./install_gp6_amd64.sh имя_файла_пакета_guitarpro6
(в качестве параметра передать ему имя файла deb-пакета Guitar Pro 6).

Собственно сам скрипт:

#!/bin/sh

# Скрипт установки Guitar Pro 6 на архитектуре amd64 для Debian-подобных ОС (Debian, Ubuntu, Kubuntu и т.д.)
# Данное решение - уродский хак, позволяющий установить 32-битную версию Guitar Pro 6 на 64-битных Debian-based системах
# Смотри также http://www.guitarplayer.ru/forum/index.php?topic=140510.msg2889582#msg2889582
# Script by Joe, 4.01.2011, GPL v3+

# ---- Секция данных

libs32='ia32-libs ia32-libs-gtk'
depend_list='libpulse0 libportaudio0 libportaudio2'

current_dir=$(pwd)
packet_folder="/tmp/$(date +%s%N)"
lib32portaudio_packet_name='lib32portaudio2'
packet32_name='libportaudio2_19+svn20071022-3.2_i386.deb'
packet64_name='lib32portaudio2_19+svn20071022-3.2_amd64'
packet_lib_url="http://ftp.fr.debian.org/debian/pool/main/p/portaudio19/$packet32_name"
packet_version='19+svn20071022-3.2'

gp6_packet_file="" # определяется по переданному параметру
gp6_packet_name='GuitarPro6'

# ---- Секция функций

# Обработка полученного аргумента
process_args() {
    if [ "$1" = "" ]; then
        echo "Использование: $0 имя_файла_пакета_guitar_pro_6"
        exit 1
    fi

    gp6_packet_file="$1"

    if ! [ -f $gp6_packet_file ]; then
        echo "Файл $gp6_packet_file не существует!"
        echo "Скопируйте данный скрипт в каталог с пакетом Guitar Pro 6."
        echo "Если это не помогло - установите в этом скрипте корректное значение переменной gp6_packet"
        exit 1
    fi
}

# Проверяет наличие aptitude
install_aptitude() {
    echo 'Проверка наличия aptitude... '
    if ! $(aptitude --help >/dev/null); then
        sudo apt-get install aptitude
        sudo aptitude update
        echo 'aptitude успешно установлен!'
    else
        echo 'OK!'
    fi
}

# Удаляет мусор от прошлой установки Guitar Pro 6 (если он есть)
remove_garbage() {
    echo 'Удаление "мусора" от предыдущей установки...'
    killall GuitarPro
    sudo dpkg -r $gp6_packet_name
    sudo aptitude -y purge $lib32portaudio_packet_name
}

# Устанавливает 32-битные библиотеки из репозитория
install_libs32() {
    echo 'Установка 32-битных библиотек...'
    sudo aptitude -y install $libs32
}

# Устанавливает зависимости
install_dependencies() {
    echo 'Установка зависимостей Guitar Pro 6...'
    sudo aptitude -y install $depend_list
}

# Создает и устанавливает пакет lib32portaudio2
install_lib32portaudio() {
    echo 'Создание пакета lib32portaudio...'
    mkdir $packet_folder
    cd $packet_folder
    wget $packet_lib_url
    dpkg --extract $packet32_name $packet64_name
    cd "$packet64_name"/usr
    rm -rf share/
    mv lib/ lib32/
    cd ..
    mkdir DEBIAN
    cd DEBIAN
    cat <<!CONTROL! > control
Package: lib32portaudio2
Source: portaudio19 ($packet_version)
Version: $packet_version
Architecture: amd64
Maintainer: myself
Installed-Size: 208
Depends: ia32-libs
Section: libs
Priority: optional
Homepage: http://www.portaudio.com/
Description: Portable audio I/O - shared library
!CONTROL!
    cd ../..
    dpkg-deb --build "$packet64_name"/

    echo 'Установка пакета lib32portaudio...'
    sudo dpkg -i "$packet64_name".deb
    sudo ldconfig

    cd "$current_dir"
    rm -rf $packet_folder
}

# Устанавливает пакет Guitar Pro 6
install_gp6_packet() {
    echo 'Установка Guitar Pro 6...'
    sudo dpkg --force-all -i $gp6_packet_file
    return
}

# ---- Секция выполнения

# Обработка аргумента коммандной строки
process_args "$1"

# Установка зависимостей
install_aptitude
remove_garbage
install_libs32
install_dependencies
install_lib32portaudio

# Установка Guitar Pro 6
install_gp6_packet
# Проверка результата установки
if [ $? != 0 ]; then
    echo 'Ошибка при установке Guitar Pro 6...'
    exit 1
fi

# Задержка, чтобы успел обработаться ярлык оконным менеджером
echo "Подождите несколько секунд..."
sleep 10

echo 'Скрипт успешно завершен! Теперь вы можете запустить Guitar Pro 6 из меню вашего оконного менеджера или создать ярлык'
exit 0

Прошу прощения, промахнулся окошком. Вот ответ на ваш комментарий: habrahabr.ru/blogs/qt_software/107698/#comment_3408605
В приведенном вами примере, функция main() знает о том, как именно происходит связь между CNotify и CPresenter. Теперь при изменении интерфейсной части CNotify придется переписывать также функцию main(). Кроме того, метод QObject::connect() выполняется в динамике, в отличие передачи объекта по интерфейсу. А значит вы лишаетесь статической проверки того, насколько вы всё правильно сделали; например, если вы сигнал closeClicked() измените на closed(), программа скомпилируется, но не будет работать корректно (уже во время выполнения программы в консоль выведется информация о том, что не получилось соединиться с несуществующим сигналом closeClicked()). А теперь представьте, что View делает совершенно другой человек, более того — менее квалифицированный в программирование. Думаю статическая типизация сэкономит немало нервов.

> Как видно из исходника, в случае использования сигналов и слотов презентер также ничего не знает о view.
Знает, просто это не так заметно. На самом деле механизм сигналов и слотов — это реализация паттерна Observer на уровне MOC-компилятора, а значит объект подписки (Subject) знает о наблюдателях (Observer), а также знает указатели на функции уведомления у Observer.

> Ну почему же не знает — он ведь передает интерфейс
Я писал не о том, что объект не знает об объекте View, а о том, что он не знает, как именно происходит связь между View и Presenter

> А оно в данном случае имеет какую-либо практическую ценность? Насколько я помню, внешний вид интерфейса в Qt меняется штатными средствами на уровне вызова одной функции «установить стиль для всего приложения».

Насчет этого я уже писал в комментарии выше. Похоже, вы не до конца поняли, что дает MVP. setStyle() и setStyleSheet() позволяют с помощью QSS изменить внешний вид элементов. MVP позволяет вам изменить сам View, т.е. на окне могут быть совершенно другие элементы, расположенные совершенно по-другому. При этом setStyle() и setStyleSheet() никто не отменяет, MVP и страницы стилей это совершенно ортогональные вещи. Более того, с помощью MVP вы можете сделать представление не окошком, а консолью, или вообще веб-формой. Так что абстрактная фабрика действительно может пригодится в случае, если ваше приложение должно быть очень гибкое в плане UI, т.е. легко менять все View в приложении в зависимости от выбранного пользователем стиля. При чем останется возможность масштабирования системы, т.е. добавления новых видом View и фабрики для них. Наверное можно вообще сделать это дело плагинами через QtPlugin, предоставив таким образом разработчикам SDK для создания собственных View.
> Но ведь объем кода для описания интерфейса и для организации сигналов — одинаков?

Ну можно обойтись вообще без IView, да. Но тогда увеличится связанность, т.е. презентеру придется знать о конкретном View, а не об интерфейсе. IView для этого и применен, для уменьшения связанности. Подробней можно прочесть тут: www.rsdn.ru/article/patterns/ModelViewPresenter.xml#EGGAC, называется Inversion of Control.

> А в текущем приложении разве не то же самое происходит когда указатель на view передается в презентер?

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

Вообще, основная идея в том, чтобы однажды написав IView, можно было бы создавать конкретные View, при этом код основного приложения абсолютно не менялся. Например, есть фабрики классов, которые выдают конкретные View (окошки вашего приложения). Допустим фабрики ClassicViewFactory, GlamourViewFactory и WebViewFactory, которые наследуются от AbstractViewFactory. Далее, создавая на этапе запуска приложения конкретную фабрику (скажем прочитав соответствующий флаг из файла настроек приложения), имеем абсолютно разный внешний вид приложения. При этом код приложения вообще не меняется. При добавлении нового стиля приложения — добавляется новая фабрика, а в написанный код добавится лишь код:
if (settings.value(«style»).toString() == «web»)
m_viewFactory = new WebViewFactory(this); // где m_viewFactory объявлена как QAbstractViewFactory *m_viewFactory;
Пришлось бы создавать в Presenter-е дополнительные публичные слоты и сигналы, и коннектить View и Presenter в контексте вашего приложения. Также объект приложения должен будет ЗНАТЬ, как именно должны связываться View и Presenter. Мне кажется, это было бы не так удобно.
Судя по cahnge-log 4.7.1, работа над QML в разгаре (http://qt.nokia.com/developer/changes/changes-4.7.1/). Используем QML в проекте, полёт нормальный. Облом был один раз, когда они выпилили эффекты, но через qmlRegisterType() эффекты легко вернулись. Таким же образом можно и стандартные виджеты передавать из C++ в QML. Всё же для новых проектов действительно не рекомендовал бы его применять — думаю еще пол-годика надо подождать, пока допилят.
>Вопрос: а почему нельзя было сделать IView наследником сразу QWidget?
Почему же нельзя, можно. Но таким образом вы «скажете», что все представления должны быть наследниками от QWidget. Если это подходит для конкретного проекта — то это нормально. Но если представление должно быть веб-страницей или консолью — то не покатит.

>Стили обычно меняются при помощи QApplication::setStyle(). Или это про другие стили?
Я имел ввиду общий вид приложения, т.е. фабрика может выдавать совершенно разные формы, главное чтобы они наследовались от интерфейсного класса
И вам привет! То что от балды писал — это точно, но статья очень понравилась. Но всё же не соглашусь с вами по поводу трактовки этого скрипта — ведь там явно указано, что этот скрипт — «literary reference», т.е. ссылка на литературу (что отлично вписывается в аналогию статьи между писателем и пользоватем консоли). Комментарий в конце "# Let's see for whom the bell tolls." приводит нас к Хемингуэю, а «whom» — это скорее «по_ком», но так будет два слова. Так что останусь при своей точке зрения, но не могу не усмотреть в вашем комментарии живость ума, так часто присущую юниксоидам :)
«Нет человека, который был бы как Остров, сам по себе, каждый человек есть часть Материка, часть Суши; и если волной снесёт в море береговой Утёс, меньше станет Европа, и так же, если смоет край мыса или разрушит Замок твой или друга твоего; смерть каждого Человека умаляет и меня, ибо я един со всем Человечеством, а потому не спрашивай, по ком звонит колокол: он звонит по Тебе». (Эрнест Хемингуэй)

В данном скрипте ищутся все процессы с фразой КТО, т.е. по КОМ звонит колокол. Прикол видимо в том, что находится только процесс этого же скрипта, т.е. колокол звонит по тебе.

echo ^G — символ звонка, т.е. будет издан звук из PC Speaker по идее. Как я понял, в скрипте ошибка — нужно использовать -n вместо -z. Сам скрипт как я его понял — написал ниже
if [ -n "`ps -fe | grep KTO`" ]; then
echo ^G
fi
Спасибо, кэп, я бы не заметил
www.stepanovpapers.com/
Правда, для них там только английские презентации.
Про X/Open в википедии есть. Да на самом деле в книге [1] написано, что все юзают echo где это возможно, несмотря на реккомендации X/Open. А я когда писал — просто не задумывался, хотя да — читаемость с echo лучше
Про echo знаю. printf использовал, т.к. X/Open призывают применять его вместо echo [1, с. 75]. Когда писал, как то не задумывался, printf — привычка с Си.
Про enca не знал, спасибо (недавно начал использовать Linux). Задача была — привести все файлы в нативный для Linux вид — т.е. автоматизировать процесс миграции.

Информация

В рейтинге
Не участвует
Откуда
Краматорск, Донецкая обл., Украина
Дата рождения
Зарегистрирован
Активность