Как удалить виджет по его objectName в PyQT5?
Как я могу удалить виджет, имея его objectName? Сейчас код выдает ошибку из-за того, что я в метод removeWidget() передаю строку, но как мне сделать так, чтобы removeWidget() удалял виджет?
self.senderText = self.sender().objectName() self.selectedTask.setText(self.sender().text()) font = self.selectedTask.font() font.setPointSize(18) font.setBold(True) self.noteText.setPlainText('') self.deletetaskButton.clicked.connect(self.deleteTask) self.selectdateButton.clicked.connect(self.selectDate) def deleteTask(self): self.tasksList.removeWidget(self.senderText)
Отслеживать
задан 14 ноя 2021 в 18:14
1 1 1 бронзовый знак
пожалуйста, предоставьте минимальный воспроизводимый пример
14 ноя 2021 в 20:12
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Используйте findChild для поиска виджета по его objectName. Сразу обращу внимание, что виджет ищется только среди непосредственных потомков родителя. В реальных условиях возможно понадобится делать рекурсивный поиск.
В Примере создаются несколько кнопок с ObjectName «button1», «button2» и т.д. Введите имя в lineedit и нажмите кнопку «delete by name». Если потомок найдется, он будет удален (можете ввести «button1» чтобы удалить кнопку или «lineedit», тогда будет удалена строка ввода)
import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QGridLayout, QWidget, QPushButton, QLineEdit from PyQt5.QtCore import QSize, QObject class MainWindow(QMainWindow): def btnClicked(self): # поиск потомка self по его имени из lineedit resbutton = self.findChild(QObject, self.lineedit.text()) if resbutton: resbutton.deleteLater() def __init__(self): QMainWindow.__init__(self) self.setMinimumSize(QSize(400, 400)) central_widget = QWidget(self) self.setCentralWidget(central_widget) self.grid_layout = QGridLayout() central_widget.setLayout(self.grid_layout) for i in range(1,10): button = QPushButton(f"i'am button") button.setObjectName(f"button") self.grid_layout.addWidget(button, i, 0) self.lineedit = QLineEdit() self.lineedit.setObjectName("lineedit") self.grid_layout.addWidget(self.lineedit, 10, 0) self.button = QPushButton("delete by name") self.grid_layout.addWidget(self.button, 10, 1) self.button.clicked.connect(self.btnClicked) if __name__ == "__main__": app = QApplication(sys.argv) mw = MainWindow() mw.show() sys.exit(app.exec())
PyQt5: первые программы

Я начинаю перевод серии уроков PyQt5 от zetcode.
PyQt5 — это набор Python библиотек для создания графического интерфейса на базе платформы Qt5 от компании Digia.
Он доступен для Python 2.x и 3.x. Этот учебник использует Python 3.
Библиотека Qt является одной из самых мощных библиотек GUI (графического интерфейса пользователя).
Установить PyQt5 на Windows можно с официального сайта библиотеки.
Установить PyQt5 на linux-системы можно с помощью любого менеджера пакетов:
sudo apt-get install python3-pyqt5 pyqt5-dev-tools
PyQt5 реализован в виде набора python-модулей. Эта библиотека имеет более 620 классов и 6000 функций и методов.
Это мультиплатформенная библиотека, которая работает на всех основных операционных системах, в том числе Unix, Windows и Mac OS.
Простой пример
Это простой пример, показывающий небольшое окно. Тем не менее, мы можем многое сделать с этим окном. Мы можем изменить его размер, развернуть его или свернуть. Это требует написания значительного объёма кода. Однако кто-то уже запрограммировал эту функциональность до нас. Поскольку эта функциональность повторяется в большинстве приложений, нет необходимости писать её снова.
PyQt5 является инструментом высокого уровня. Если бы мы писали это на более низком уровне, следующий пример кода легко мог бы растянуться на сотни строк:
Приведенный выше код показывает небольшое окно на экране.
Здесь мы делаем необходимые импорты. Основные виджеты расположены в PyQt5.QtWidgets.
Каждое приложение PyQt5 должно создать объект приложения (экземпляр QApplication). Параметр sys.argv это список аргументов командной строки. Скрипты Python можно запускать из командной строки. Это способ, которым мы можем контролировать запуск наших сценариев.
Виджет QWidget это базовый класс для всех объектов интерфейса пользователя в PyQt5. Мы предоставляем конструктор по умолчанию для QWidget. Конструктор по умолчанию не имеет родителя. Виджет без родителей называется окно.
Метод resize() изменяет размеры виджета. Он стал 250 пикселей в ширину и 150 в высоту.
Метод move() двигает виджет на экране на координату x=300, y=300.
Здесь мы задаём заголовок нашего окна.
Метод show() отображает виджет на экране. Виджет сначала создаётся в памяти, и только потом (с помощью метода show) показывается на экране.
Наконец, мы попадаем в основной цикл приложения. Обработка событий начинается с этой точки. Основной цикл получает события от оконной системы и распределяет их по виджетам приложения. Основной цикл заканчивается, если мы вызываем метод exit() или главный виджет уничтожен. Метод sys.exit() гарантирует чистый выход. Вы будете проинформированы, как завершилось приложение.
Метод exec_ () имеет подчеркивание. Это происходит потому, что exec является ключевым словом в python 2.
Значок приложения
Значок приложения — небольшое изображение, которое обычно отображается в верхнем левом углу заголовка. В следующем примере мы покажем, как сделать это в PyQt5. Мы также представим некоторые новые методы.
Не забудьте также скачать какую-нибудь иконку 🙂
Предыдущий пример был написан в процедурном стиле. Язык программирования Python поддерживает как процедурный, так и объектно-ориентированный стили программирования. Программирование в PyQt5 означает программирование в ООП.
Три важные вещи в объектно-ориентированном программировании это классы, данные и методы. Здесь мы создаем новый класс Example. Класс Example наследуется от класса QWidget. Это означает, что мы вызываем два конструктора: первый для класса Example и второй для родительского класса. Функция super() возвращает родительский объект Example с классом, и мы вызываем его конструктор.
Создание GUI делегируется методу initUI().
Все три метода были унаследованы от класса QWidget.
Метод setGeometry() делает две вещи: помещает окно на экране и устанавливает его размер. Первые два параметра х и у — это позиция окна. Третий — ширина, и четвертый — высота окна. На самом деле, он сочетает в себе методы resize() и move() в одном методе.
Последний метод устанавливает иконку приложения. Чтобы сделать это, мы создали объект QIcon. QIcon получает путь к нашей иконке для отображения.
Создаются объекты application и Example. Запускается основной цикл.
Подсказки
Мы можем предоставить всплывающую подсказку для любого из виджетов.
QWidget widget'QPushButton widget'В этом примере мы покажем подсказку для двух виджетов PyQt5.
Этот статический метод устанавливает шрифт, используемый для отображения подсказки. Мы используем шрифт 10px SansSerif.
QWidget widget'Чтобы создать всплывающую подсказку, мы вызываем метод setToolTip(). Мы можем использовать форматирование текста.
QPushButton widget'Мы создаем виджет кнопки и устанавливаем подсказку для него.
Меняем размер кнопки и перемещаем относительно окна. Метод sizeHint() дает рекомендуемый размер для кнопки.
Закрытие окна
Очевидный способ закрыть окно, это нажать на крестик. В следующем примере мы покажем, как мы можем программно закрыть наше окно. Мы кратко рассмотрим сигналы и слоты.
В этом примере, мы создаем кнопку выхода. После нажатия на кнопку, приложение завершается.
Мы создаем кнопку. Кнопка является экземпляром класса QPushButton. Первый параметр конструктора - название кнопки. Вторым параметром является родительский виджет. Родительский виджет является виджетом Example, который наследуется от QWidget.
Система обработки событий в PyQt5 построена на механизме сигналов и слотов. Если мы нажмем на кнопку, вызовется сигнал "нажатие". Слот может быть слот Qt или любая Python функция.
QCoreApplication содержит главный цикл обработки; он обрабатывает и диспетчеризирует все события. Метод instance() дает нам его текущий экземпляр.
Обратите внимание, что QCoreApplication создается с QApplication. Сигнал «нажатие» подключен к методу quit(), который завершает приложение. Коммуникация осуществляется между двумя объектами: отправителя и приемника. Отправитель кнопка, приемник — объект приложения.
Message Box
По умолчанию, если мы нажмем на крестик, QWidget закрывается. Иногда мы хотим изменить это поведение по умолчанию, например, если у нас есть открытый файл, в котором мы сделали некоторые изменения. Мы показываем окно с сообщением для подтверждения действия.
Если мы закрываем QWidget, генерируется QCloseEvent. Чтобы изменить поведение виджета, нам нужно переопределить обработчик события closeEvent().
Мы показываем окно с сообщением и с двумя кнопками: Yes и No. Первая строка отображается в заголовке окна. Вторая строка является текстовым сообщением и отображается в диалоговом окне. Третий аргумент определяет комбинацию кнопок, появляющихся в диалоге. Последний параметр - кнопка по умолчанию. Это кнопка, на которой изначально установлен фокус клавиатуры. Возвращаемое значение хранится в переменной reply.
Здесь мы проверяем возвращаемое значение. Если мы нажмем на кнопку Yes, мы принимаем событие, которое приводит к закрытию виджета и приложения. В противном случае мы будем игнорировать событие закрытия.
Центрирование окна на экране
Следующий скрипт показывает, как мы можем центрировать окно на рабочем столе.
Класс QtWidgets.QDesktopWidget предоставляет информацию о компьютере пользователя, в том числе о размерах экрана.
Код, который будет центрировать окно, находится в нами созданном методе center().
Мы получаем прямоугольник, определяющий геометрию главного окна. Это включает в себя любые рамки окна.
Мы получаем разрешение экрана нашего монитора. И с этим разрешением, мы получаем центральную точку.
Наш прямоугольник уже имеет ширину и высоту. Теперь мы установили центр прямоугольника в центре экрана. Размер прямоугольника не изменяется.
Мы двигаем верхний левый угол окна приложения в верхний левый угол прямоугольника qr, таким образом, центрируя окно на нашем экране.
В этой части урока PyQt5 мы рассмотрели некоторые основы.
Для вставки кода на Python в комментарий заключайте его в теги
- Модуль csv - чтение и запись CSV файлов
- Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
- Онлайн-обучение Python: сравнение популярных программ
- Книги о Python
- GUI (графический интерфейс пользователя)
- Курсы Python
- Модули
- Новости мира Python
- NumPy
- Обработка данных
- Основы программирования
- Примеры программ
- Типы данных в Python
- Видео
- Python для Web
- Работа для Python-программистов
- Сделай свой вклад в развитие сайта!
- Самоучитель Python
- Карта сайта
- Отзывы на книги по Python
- Реклама на сайте
Описание Класса QGridLayout
[модуль QtGui]
QGridLayout занимает отведенное ему место (отведенное родительский компоновщиком или parentWidget()), разбивает его на строки и столбцы и помещает каждый подконтрольный виджет в соответствующую ячейку.
Столбцы и строки ведут себя одинаково; мы обсудим столбцы, но есть эквивалентные функции для строк.
Каждый столбец имее минимальную ширину и фактор растяжения. Минимальная ширина - это максимальное значение из значения, установленного с помощью setColumnMinimumWidth(), и минимальных ширин всех виджетов, расположенных в колонке. Фактор растяжения устанавливается с помощью setColumnStretch() и определяет, сколько доступного места сверх минимального размера займет колонка.
Обычно, каждый подконтрольный виджет или компоновщик помещается в свою ячейку с помощью addWidget(). Виджет также можно поместить в несколько ячеек, чтобы он занимал несколько строк и колонок, используя перегруженные addItem() и addWidget(). Если Вы делаете это, то QGridLayout попытается распределить его размер по колонкам/строкам (основываясь на факторах растяжения).
Для удаления виджета из компоновщика вызовите remove(). Вызов QWidget::hide() для виджета также эффективно удаляет виджет из компоновщика до вызова QWidget::show().
Следующая иллюстрация показывает фрагмент диалога с сеткой, состоящей из пяти колонок и трех строк (сетка показана пурпурным цветом):

Колонки 0, 2 и 4 в данном диалоге содержат QLabel, QLineEdit и QListBox. Колонки 1 и 3 являются разделителями, заданными с помощью setColumnMinimumWidth(). Строка 0 содержит три объекта QLabel, строка 1 - из трех объектов QLineEdit, а строка 2 - из трех объектов QListBox. Мы использовали колонки-разделители (1 и 3) для установки правильного расстояния между колонками.
Обратите внимание, что колонки и строки имеют не одинаковые ширины и высоты. Если Вы хотите, чтобы две колонки имели одинаковую ширину, Вы должны непосредстенно установить в одинаковые значения их минимальные размеры и факторы растяжения. Вы должны сделать это с помощью setColumnMinimumWidth() и setColumnStretch().
Если QGridLayout не является компоновщиком верхнего уровня, (т.е. не управляет всем пространством виджета и его дочерними объектами), то Вы должны добавить его в родителький компоновщик после создания, но прежде, чем Вы что-либо начнете делать с ним. Нормальный способ добавления компоновщика - это вызов addLayout() в родительком виджете.
Как только Вы добавили Ваш компоношик, Вы можете, с помощью addWidget(), addItem() и addLayout(), добавлять другие виджеты и компоновщики в ячейки Вашего компоновщика.
QGridLayout также учитывает две ширины: ширину границы и расстояние между соседними элементами. Ширина границы - это ширина незанимаемого пространства около каждой из четырех сторон QGridLayout. Расстояние между соседними элементами - это пространство, автоматически вставляемое между соседними ячейками.
Ширина границы по умолчанию и расстояние между виджетами зависят от стиля. По умолчанию в стилях Qt ширина границы равна 9 для виджетов и 11 для окон верхнего уровня.
Описание Функций-Членов
QGridLayout::QGridLayout ( QWidget * parent )
Создает новый QGridLayout с родительским виджетом parent. Изначально компоновщик имеет одну строку и одну колонку и будет расширен при добавлении новых элементов.
QGridLayout::QGridLayout ()
Создает новый компоновщик с сеткой.
Вы должны будете вставить этот компоновщик в другой компоновщик. Вы можете в любое время вставлять виджеты и компоновщики в данный компоновщик, но выравнивание не будет производиться до момента, когда Вы вставите данный компоновщик в другой.
QGridLayout::~QGridLayout ()
Разрушает компоновщик с сеткой. Управление геометрией останавливается если это компоновщик с сеткой верхнего уровня.
Подконтрольные виджеты не разрушаются.
void QGridLayout::addItem ( QLayoutItem * item, int row, int column, int rowSpan = 1, int columnSpan = 1, Qt::Alignment alignment = 0 )
Добавляет элемент item в позицию row, column, растягивая его на rowSpan строк и columnSpan колонок, и выравнивая его в соответствии с alignment. Если rowSpan и/или columnSpan равны -1, то элемент будет растянут до правого и/или нижнего края соответственно. Компоновщик становится владельцем item.
Внимание: Не используйте данную функцию для добавления дочерних компоновщиков и дочерних виджетов. Используйте addLayout() или addWidget() вместо этого.
void QGridLayout::addLayout ( QLayout * layout, int row, int column, Qt::Alignment alignment = 0 )
Размещает компоновщик layout в позицию сетки (row, column). Верхняя левая поздиция - это (0, 0).
Выравнивание задается с помощью alignment. По умолчани выравнивание равно 0, что означает заполнение виджетом всей ячейки.
Ненулевое значение выравнивания означает, что компоновщик не должен увеличиваться для заполнения всего доступного пространства, а использовать sizeHint().
layout становится дочерним объектом компоновщика с сеткой.
void QGridLayout::addLayout ( QLayout * layout, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment = 0 )
Данная перегруженная функция-член создана для удобства. Ее поведение аналогично поведению вышеприведенной функции.
Эта версия добавляет компоновщик layout в ячейку сетки, растягивая его на несколько строк/столбцов. Начальная ячейка (row, column) растягивается на rowSpan строк и columnSpan столбцов.
Если rowSpan и/или columnSpan равно -1, то компоновщик растягивается до нижнего и/или правого края соответственно.
void QGridLayout::addWidget ( QWidget * widget, int row, int column, Qt::Alignment alignment = 0 )
Добавляет переданный виджет widget в ячейку сетки (row, column). По умолчанию это верхняя-левая позиция (0, 0).
Выравнивание задается с помощью alignment. По умолчани выравнивание равно 0, что означает заполнение виджетом всей ячейки.
void QGridLayout::addWidget ( QWidget * widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = 0 )
Данная перегруженная функция-член создана для удобства. Ее поведение аналогично поведению вышеприведенной функции.
Эта версия добавляет виджет widget в ячейку сетки, растягивая его на несколько строк/столбцов. Начальная ячейка (row, column) растягивается на rowSpan строк и columnSpan столбцов. Выравнивание в ячейке будет равно alignment.
Если rowSpan и/или columnSpan равно -1, то виджет растягивается до нижнего и/или правого края соответственно.
QRect QGridLayout::cellRect ( int row, int column ) const
Возвращает прямоугольник ячейки, занимающей в сетке позицию (row, column). Возвращает неверный прямоугольник, если row или column за пределами сетки.
Внимание: в текущей версии Qt данная функция не возвращает верного значения до вызова setGeometry(), т.е. пока parentWidget() не видим.
int QGridLayout::columnCount () const
Возвращает количество столбцов в сетке.
int QGridLayout::columnMinimumWidth ( int column ) const
Возвращает ширину колонки column.
int QGridLayout::columnStretch ( int column ) const
Возвращает фактор растяжения колонки column.
void QGridLayout::getItemPosition ( int index, int * row, int * column, int * rowSpan, int * columnSpan )
Возвращает позицию элемента с индексом index.
Переданные переменные row и column заполняются позициями элемента в компоновщике, а переменные rowSpan и columnSpan возвращаются вертивальным и горизонтальным растяжениями.
Qt::Corner QGridLayout::originCorner () const
Возвращает угол, используемый для расположения сетки, т.е. для позиции (0, 0).
int QGridLayout::rowCount () const
Возвращает количество строк в сетке.
int QGridLayout::rowMinimumHeight ( int row ) const
Возвращает минимальную ширину строки row.
int QGridLayout::rowStretch ( int row ) const
Возвращает фактор растяжения строки row.
void QGridLayout::setColumnMinimumWidth ( int column, int minSize )
Устанавливает минимальную ширину столбца column в minSize пикселей.
void QGridLayout::setColumnStretch ( int column, int stretch )
Устанавливает фактор растяжения столбца column в stretch. Первый столбец имеет номер 0.
Фактор растяжения устанавливается относительно других колонок в сетке. Столбец с большим фактором растяжения при заполнении свободного пространства растягивается больше.
По умолчанию фактор растяжения равен 0. Если фактор растяжения равен 0 и никакая другая колонка в данной сетке не может расти, то колонка, все таки может расти.
Альтернативный подход состоит в добавлении интервала с помощью addItem() с QSpacerItem.
void QGridLayout::setOriginCorner ( Qt::Corner corner )
Устанавливает угол сетки, т.е. ячейки (0, 0) в corner.
void QGridLayout::setRowMinimumHeight ( int row, int minSize )
Устанавливает минимальный размер строки row в minSize пикселей.
void QGridLayout::setRowStretch ( int row, int stretch )
Устанавливает фактор растяжения строки row в stretch. Первая строка имеет номер 0.
Фактор растяжения устанавливается относительно других строк в сетке. Строка с большим фактором растяжения при заполнении свободного пространства растягивается больше.
По умолчанию фактор растяжения равен 0. Если фактор растяжения равен 0 и никакая другая строка в данной сетке не может расти, то строка, все таки может расти.
Работа с картой¶
Виджет “карта” (Map Canvas) является одним из наиболее важных, так как именно он отвечает за отображение карты, состоящей из наложенных друг на друга слоёв, и позволяет взаимодействовать как со всей картой, так и с отдельными слоями. Виджет отображает только часть карты, заданную текущим охватом. Взаимодействие выполняется при помощи инструментов карты (map tools): среди которых присутствуют инструменты панорамирования, масштабирования, определения слоёв, измерения, редактирования и другие. Как и в других программах, активным в каждый момент времени может быть только один инструмент, при необходимости выполняется переключение между ними.
Карта реализуется классом QgsMapCanvas модуля qgis.gui . В основе реализации лежит Qt Graphics View framework. Фреймворк предоставляет пользователю поверхность для рисования и объект для отображения пользовательских элементов, а также даёт возможность взаимодействовать с ними. Предполагается, что читатель достаточно знаком с Qt чтобы разобраться в основных понятиях сцены, вида и элементов. Если это не так, пожалуйста, ознакомьтесь с описанием фреймворка.
Всякий раз, когда пользователь выполняет панорамирование, масштабирование (или любое другое действие, вызывающее обновление карты), происходит перерисовка карты в пределах текущего охвата. Отрисовка слоёв выполняется в изображение (за это отвечает класс QgsMapRenderer ), которое затем отображается на карте. Графическим объектом (в терминах фреймвока Qt — graphics view), отвечающим за отображение карты, является класс QgsMapCanvasMap . Этот же класс следит за обновлением карты. Помимо этого объекта, который служит фоном, может существовать множество элементов карты. Обычно, в роли элементов карты выступают “резиновые” линии (используемые при измерении и редактировании слоёв) или маркеры вершин. Чаще всего элементы карты используются для визуализации работы инструментов карты. Например, при создании нового полигона, инструмент карты создает “резиновый” элемент карты, показывающий текущую форму полигона. Все элементы карты являются наследниками QgsMapCanvasItem и добавляют свой функционал к базовому объекту QGraphicsItem .
Таким образом, архитектурно карта состоит из трёх элементов:
- карта — для отображения данных,
- элементы карты — дополнительные объекты, которые можно отобразить на карте,
- инструменты карты — обеспечивают взаимодействие с картой.
Встраивание карты¶
Так как карта это такой же элемент интерфейса, как и любой другой виджет Qt, её использование, создание и отображение весьма просто:
canvas = QgsMapCanvas() canvas.show()
Этот код создаст новое окно с картой. Точно так же можно встраивать карту в существующий виджет или окно. При использовании Qt Designer и файлов .ui удобно делать так: на форму положить QWidget и объявить его новым классом, установив в качестве имени класса QgsMapCanvas и qgis.gui в качестве заголовочного файла. Всё остальное сделает программа pyuic4 . Как видите, это очень простой и удобный способ встраивания карты в приложение. Ещё один способ — создать виджет карты и другие элементы интерфейса динамически (в качестве дочерних объектов основного или диалогового окна) и разместить их на компоновке.
По умолчанию, фон карты чёрный, сглаживание при отрисовке отключено. Чтобы установит цвет фона в белый и активировать сглаживание выполните:
canvas.setCanvasColor(Qt.white) canvas.enableAntiAliasing(True)
(если вас интересует, то приставка Qt используется модулем PyQt4.QtCore а Qt.white это один из предварительно заданных экземпляров QColor .)
Теперь можно добавить несколько слоёв. Сначала слой необходимо открыть и добавить его к списку слоёв карты. Затем нужно установить охват и добавить слои к карте:
layer = QgsVectorLayer(path, name, provider) if not layer.isValid(): raise IOError, "Failed to open the layer" # добавляем слой к списку QgsMapLayerRegistry.instance().addMapLayer(layer) # устанавливаем охват карты равный охвату слоя canvas.setExtent(layer.extent()) # добавляем слои на карту canvas.setLayerSet( [ QgsMapCanvasLayer(layer) ] )
После выполнения этих команд на карте должен отобразиться загруженный слой.
Использование инструментов карты¶
Следующий пример показывает как создать окно с картой и основными инструментами для панорамирования и масштабирования карты. Для каждого инструмента создаётся свое действие: за панорамирование отвечает QgsMapToolPan , за увеличение и уменьшение масштаба — QgsMapToolZoom . Действия настроены на работу в режиме переключателя и позже будут связанны с инструментами, что позволит автоматически отслеживать переключение между ними. Когда инструмент карты активируется, его действие помечается как активное, а действие, связанное с предыдущим инструментом, — как неактивное. За активацию инструментов карты отвечает метод setMapTool() .
from qgis.gui import * from PyQt4.QtGui import QAction, QMainWindow from PyQt4.QtCore import SIGNAL, Qt, QString class MyWnd(QMainWindow): def __init__(self, layer): QMainWindow.__init__(self) self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(Qt.white) self.canvas.setExtent(layer.extent()) self.canvas.setLayerSet( [ QgsMapCanvasLayer(layer) ] ) self.setCentralWidget(self.canvas) actionZoomIn = QAction(QString("Zoom in"), self) actionZoomOut = QAction(QString("Zoom out"), self) actionPan = QAction(QString("Pan"), self) actionZoomIn.setCheckable(True) actionZoomOut.setCheckable(True) actionPan.setCheckable(True) self.connect(actionZoomIn, SIGNAL("triggered()"), self.zoomIn) self.connect(actionZoomOut, SIGNAL("triggered()"), self.zoomOut) self.connect(actionPan, SIGNAL("triggered()"), self.pan) self.toolbar = self.addToolBar("Canvas actions") self.toolbar.addAction(actionZoomIn) self.toolbar.addAction(actionZoomOut) self.toolbar.addAction(actionPan) # создаем инструменты карты self.toolPan = QgsMapToolPan(self.canvas) self.toolPan.setAction(actionPan) self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in self.toolZoomIn.setAction(actionZoomIn) self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out self.toolZoomOut.setAction(actionZoomOut) self.pan() def zoomIn(self): self.canvas.setMapTool(self.toolZoomIn) def zoomOut(self): self.canvas.setMapTool(self.toolZoomOut) def pan(self): self.canvas.setMapTool(self.toolPan)
Этот код можно сохранить в файл, например, mywnd.py и попробовать выполнить в Консоли Python QGIS. Код ниже показывает как поместить текущий выделенный слой на созданную только что карту:
import mywnd w = mywnd.MyWnd(qgis.utils.iface.activeLayer()) w.show()
Перед этим необходимо убедиться, что файл mywnd.py находится в каталоге где Python ищет модули ( sys.path ). Если это не так, просто добавьте его: sys.path.insert(0, '/my/path') — иначе импорт завершится с ошибкой, из-за того, что модуль не найден.
Резиновые полосы и маркеры вершин¶
Для отображения дополнительных данных поверх карты используются элементы карты. Можно как создавать свои собственные элементы карты (рассматривается дальше), так и использовать существующие классы: QgsRubberBand для рисования полигонов или полилиний, и QgsVertexMarker для рисования точек. Оба этих класса работают в координатах карты, поэтому фигуры автоматически перемещаются/масштабируются при панорамировании и масштабировании карты
Показать полилинию можно так:
r = QgsRubberBand(canvas, False) # False = не полигон points = [ QgsPoint(-1,-1), QgsPoint(0,1), QgsPoint(1,-1) ] r.setToGeometry(QgsGeometry.fromPolyline(points), None)
r = QgsRubberBand(canvas, True) # True = полигон points = [ [ QgsPoint(-1,-1), QgsPoint(0,1), QgsPoint(1,-1) ] ] r.setToGeometry(QgsGeometry.fromPolygon(points), None)
Обратите внимание, что узлы полигона представлены не плоским списком: на самом деле это список границ полигона. Первое кольцо описывает внешний контур, все остальные (не обязательные) — соответствуют дыркам в полигоне.
Резиновые полосы можно настраивать, а именно менять их цвет и толщину:
r.setColor(QColor(0,0,255)) r.setWidth(3)
Элементы карты связанны с графической сценой карты. Их можно скрыть (а потом снова отобразить) вызывая функции func: hide и show() . Для полного удаления элемента необходимо удалить его из графической сцены:
canvas.scene().removeItem(r)
(при использовании C++ можно просто удалить элемент, однако в Python del r удалит только ссылку, а сам объект останется на месте, т.к. его владельцем является карта)
Резиновые полосы можно использовать и для рисования точек, но для этих целей существует специальный класс QgsVertexMarker ( QgsRubberBand может нарисовать только прямоугольник вокруг заданной точки).
Вот так можно создать маркер вершины:
m = QgsVertexMarker(canvas) m.setCenter(QgsPoint(0,0))
Следующий фрагмент кода показывает как создается красный крестик в точке [0,0]. Можно настроить тип значка, его размер, цвет и толщину пера:
m.setColor(QColor(0,255,0)) m.setIconSize(5) m.setIconType(QgsVertexMarker.ICON_BOX) # или ICON_CROSS, ICON_X m.setPenWidth(3)
Для временно скрытия и последующего отображения маркеров используется тот же подход, что и для резиновых полос.
Создание собственных инструментов карты¶
TODO: how to create a map tool
Создание собственных элементов карты¶
TODO: how to create a map canvas item