Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/103: Рейтинг темы: голосов - 103, средняя оценка - 4.71
 Аватар для GmDio
6 / 5 / 1
Регистрация: 06.06.2022
Сообщений: 68

Разница между PyQT 5 и PyQT 6

15.06.2022, 14:57. Показов 28003. Ответов 20

Студворк — интернет-сервис помощи студентам
Добрый день, форумчане. Прошел тут курс всеми вами любимого автора, познакомился с GUI TKinter, и по вашим советам решил освоить PyQT.
Чтобы не допустить ошибок решил сперва тут посоветоваться.

1. Как я обратил внимание есть 2 популярные версии PyQT 5 и PyQT 6. Интересует разница между этими версиями. Просто одна новее другой или все-таки различия колоссальны? Если так, то какую актуальнее начать изучать.
2. Посоветуйте литературу (лучше в формате видеоуроков), которая поможет быстрее и лучше этот модуль изучить.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.06.2022, 14:57
Ответы с готовыми решениями:

Из QT в PyQt
Здравствуйте, подскажите правильно ли у меня получился перевод из QT в PyQt? Интересует именно выполнение класса QCoreApplication и...

PyQT+OpenCV
Имеется следующий код, который работает в консоли (распознавание номерных знаков) class Video(): cap = cv2.VideoCapture(0) ...

Paint pyqt
Добрый вечер, помогите разобраться с кодом я в Python (pyqt, Desinger) новичок. Можете обяснить по подробнее с "Class Canvas"...

20
Модератор
Эксперт Python
 Аватар для Fudthhh
2696 / 1602 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
16.06.2022, 16:30
Лучший ответ Сообщение было отмечено GmDio как решение

Решение

Цитата Сообщение от GmDio Посмотреть сообщение
Как я обратил внимание есть 2 популярные версии PyQT 5 и PyQT 6.
Разницы особо нет (если не заглядывать под капот) в основном все то же самое, немного изменены названия методов (Например: QDialog.exec_ изменен на QDialog.exec), где то добавили перегрузки функций для удобства.

Цитата Сообщение от GmDio Посмотреть сообщение
Посоветуйте литературу (лучше в формате видеоуроков), которая поможет быстрее и лучше этот модуль изучить.
Нет ничего лучше офф. доков, наглядно, доступно, бери да пользуйся (там даже куча примеров есть).
0
 Аватар для GmDio
6 / 5 / 1
Регистрация: 06.06.2022
Сообщений: 68
16.06.2022, 16:33  [ТС]
Fudthhh, спасибо большое, я правильно понял, что если начинать с ним знакомиться, то сразу с шестой версии? И еще, как правильнее с ним работать? В смысле смотреть в сторону QT Designer или учиться обходиться без него?
Просто помню в давние времена многие хейтили Dreamviewer при верстке.
0
Модератор
Эксперт Python
 Аватар для Fudthhh
2696 / 1602 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
17.06.2022, 07:32
Цитата Сообщение от GmDio Посмотреть сообщение
смотреть в сторону QT Designer или учиться обходиться без него
Лучше писать руками, код чище, есть понимание где что и как работает.

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

Добавлено через 6 минут
Добавляю еще, уже обсуждали в какой то другой теме этот же вопрос, и мне противопоставили, что этот инструмент можно использовать при распределении задач, допустим кто то рисует формы, а кто-то пишет логику, это сомнительно, во первых: откуда тебе знать как создатель форм назвал переменные, даже если он их изменил, тебе придется лично запускать QtDesigner проверять названия переменных и писать логику (можно конвертировать из *.ui в *.py, но ты увидишь портянку класса, которую просто невозможно читать), во вторых: код будет абсолютно ненаглядным, т.к. при загрузке формы с *.ui ты будешь писать логику и ide не будет тебе ничего подсвечивать (да можно этого избежать написав аннотации, но это куча лишней работы).
1
1713 / 580 / 76
Регистрация: 10.04.2009
Сообщений: 9,337
17.06.2022, 07:55
здравствуйте, а есть возможность из питона сделать кросс для веба, настольных и мобильных приложений, или как конвертировать наиболее быстро?
0
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 939
17.06.2022, 10:42
Цитата Сообщение от GmDio Посмотреть сообщение
Посоветуйте литературу (лучше в формате видеоуроков), которая поможет быстрее и лучше этот модуль изучить.
Если литературу, то из русского это Прохоренок, а на англ.языке тут (хотите 5 хотите 6 версия pyside или pyqt).

Добавлено через 2 минуты
Цитата Сообщение от GmDio Посмотреть сообщение
лучше в формате видеоуроков
не встречал нормальных уроков в рунете, лучше оф.документация или если с ней пока тяжело, то книги)

Добавлено через 35 секунд
PS тоже норм. курс http://it.kgsu.ru/Python_Qt/oglav.html
0
Модератор
Эксперт Python
 Аватар для Fudthhh
2696 / 1602 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
17.06.2022, 10:56
Михалыч, зная основы, у меня не возникало больших трудностей изучения Qt по их документации, написав пару-тройку простых виджетов, уже понимаешь как писать приложения, больше всего наверное вызвало сложности:
1) Как написать свой QAbstractModelItem для QTreeView
2) Как заставить синхронно(да, да, именно синхронно) писать в QSerialPort, QTcpSocket портянку команд, без зависания интерфейса.

Все остальное достаточно просто осваивается, у всех виджетов есть примеры. (Не знаю на счет PySide документации, т.к. изучал по документации по СИ, разница только в оформлении, а команды одинаковые)
0
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 939
17.06.2022, 11:15
Цитата Сообщение от Fudthhh Посмотреть сообщение
т.к. изучал по документации по СИ
Многие говорят, что у Qt хорошая документация) Но мне в начале не хватило в документации к PyQt именно стартового набора (для "самых маленьких") примеров, что бы взял копипаст и запустил. А потом начал этот пример препарировать)))

Например, QTabWidget понятно, что таблица, а примера нет. Оттого и не понятно что с ней делать. И это по началу приводит к некоторому замешательству)
0
0 / 0 / 0
Регистрация: 17.06.2022
Сообщений: 2
21.06.2022, 21:42
А можешь подсказать, что это за курс, который ты прошел?
я хотел написать в личку, но какой-то древний форум, не знаю как это сделать )

Дай плиз ссылку на курс
0
 Аватар для GmDio
6 / 5 / 1
Регистрация: 06.06.2022
Сообщений: 68
21.06.2022, 22:11  [ТС]
1gga, Ссылку не буду постить. Набери в любом поисковике «Русаков Python от нуля до гуру», но местные не советуют. Основы я понял, но сейчас пришла необходимость учить С#

Добавлено через 3 минуты
Понял, спасибо!
1
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,144
Записей в блоге: 243
26.06.2022, 00:13
Лучший ответ Сообщение было отмечено Fudthhh как решение

Решение

Несколько базовых изменений в PyQt6 касательно графики на шейдерном OpenGL

1. OpenGL-классы перенесли в отдельное пространство имён PyQt6.QtOpenGL:

PyQt5:
Python
1
2
from PyQt5.QtGui import (QOpenGLBuffer, QOpenGLShader, QOpenGLShaderProgram,
                         QOpenGLTexture)
PyQt6:

Python
1
2
from PyQt6.QtOpenGL import (QOpenGLBuffer, QOpenGLShader, QOpenGLShaderProgram,
                            QOpenGLTexture)
2. Класс QOpenGLWidget перенесли в пространство имён PyQt6.QtOpenGLWidgets:

PyQt5:
Python
1
from PyQt5.QtWidgets import QApplication, QOpenGLWidget
PyQt6:

Python
1
from PyQt6.QtOpenGLWidgets import QOpenGLWidget
3. Изменён enum для типов шейдеров:

PyQt5:
Python
1
2
self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertShaderSrc)
self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragShaderSrc)
PyQt6:

Python
1
2
self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Vertex, vertShaderSrc)
self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Fragment, fragShaderSrc)
4. Изменён enum Target текстуры:

PyQt5:
Python
1
self.texture = QOpenGLTexture(QOpenGLTexture.Target2D)
PyQt6:

Python
1
self.texture = QOpenGLTexture(QOpenGLTexture.Target.Target2D)
5. Изменён enum для настройки фильтров текстуры:

PyQt5:
Python
1
self.texture.setMinMagFilters(QOpenGLTexture.Linear, QOpenGLTexture.Linear)
PyQt6:

Python
1
self.texture.setMinMagFilters(QOpenGLTexture.Filter.Linear, QOpenGLTexture.Filter.Linear)
6. Изменён enum для WrapMode:

PyQt5:
Python
1
self.texture.setWrapMode(QOpenGLTexture.ClampToEdge)
PyQt6:

Python
1
self.texture.setWrapMode(QOpenGLTexture.WrapMode.ClampToEdge)
7. Изменён enum для установки атрибутов приложения:

PyQt5:
Python
1
QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
PyQt6:

Python
1
QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
0
36 / 3 / 1
Регистрация: 30.06.2016
Сообщений: 93
30.01.2023, 10:14
Тоже начал разбираться с PyQt
Что могу сказать, даже на момент начала 23года, уроков, примеров на гитхабе, книг и прочего по PyQT5 больше.
Да, есть отличия 5 от 6 небольшие. Но как мне кажется, быстрее будет 5ку освоить, потом переписать на 6ку
0
Модератор
Эксперт Python
 Аватар для Fudthhh
2696 / 1602 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
30.01.2023, 11:06
Цитата Сообщение от Spirit412 Посмотреть сообщение
Но как мне кажется, быстрее будет 5ку освоить, потом переписать на 6ку
Тогда может быть вообще начать изучать python первой версии, потом переписать на вторую, а затем и на третью.
Если уж совсем легко, то можно начать с фортана и идти по эволюции языков программирования, попутно переписывая свой скрипт под них.
0
36 / 3 / 1
Регистрация: 30.06.2016
Сообщений: 93
30.01.2023, 11:57
А чем вам фортран или паскаль не нравится? Есть языки на которых не пишут приложения. Языки изначально разработанные для студентов.
Мы говорим здесь не про версию пайтона, а про версию фреймворка.
Если человеку сложно по докам изучать, то информации и учебных материалов по 5ке больше будет.
0
 Аватар для Михалыч
1011 / 355 / 59
Регистрация: 28.02.2013
Сообщений: 939
30.01.2023, 13:24
Цитата Сообщение от Spirit412 Посмотреть сообщение
информации и учебных материалов по 5ке больше будет
Пока наверное так, по крайней мере в рунете.
Но ИМХО, лучше учить новую версию PyQt6, что бы не привыкать к старой, а потом переучиваться)
Тем более если посмотреть на англ.яз. есть хорошие материалы для начинающих по PyQt6 (например тут).
Я вот себе тоже обещаю все переписать на PyQt6, но никак от "пятерки" отказаться не могу хотя надо бы.
Т.е. если бы я для себя по новой начал учить PyQt, то непременно шестую версию.
1
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,144
Записей в блоге: 243
30.01.2023, 14:01
Неплохой вводный туториал по PyQt6: https://zetcode.com/pyqt6/ В последнем уроке даже разбирается игра Тетрис. Если не хотите изучать на английском, а лучше всего изучать на нём, то можно нагуглить перевод этого туториала на русский или переводить с помощью Google Translate.

Пара отличий:

1. Изменён enum для режима открытия файла:

PyQt5:
Python
1
2
3
file = QFile(path)
if not file.open(QIODevice.ReadOnly):
    print("Failed to open the file: " + path)
PyQt6:

Python
1
2
3
file = QFile(path)
if not file.open(QIODevice.OpenModeFlag.ReadOnly):
    print("Failed to open the file: " + path)
2. Метод QApplication.exec_() был переименован в QApplication.exec()

PyQt5:
Python
1
2
3
4
5
import sys
from PyQt5.QtWidgets import QApplication
 
app = QApplication(sys.argv)
sys.exit(app.exec_())
PyQt6:

Python
1
2
3
4
5
import sys
from PyQt6.QtWidgets import QApplication
 
app = QApplication(sys.argv)
sys.exit(app.exec())
2
Модератор
Эксперт Python
 Аватар для Fudthhh
2696 / 1602 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
30.01.2023, 15:29
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Изменён enum для режима открытия файла
Можно использовать и старым способом, криминального ничего нет.

Цитата Сообщение от 8Observer8 Посмотреть сообщение
Метод QApplication.exec_() был переименован в QApplication.exec()
Не совсем верное утверждение, оба метода существует, но "exec_" считается устаревшим, и возможно в будущих версиях этот метод будет удален.
1
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,144
Записей в блоге: 243
30.01.2023, 21:57
Я почти всегда проверяю свои утверждения перед публикацией. Использую PyQt 6.3.0.

Цитата Сообщение от Fudthhh Посмотреть сообщение
оба метода существует, но "exec_" считается устаревшим
У меня не работает "exec_":

AttributeError: 'QApplication' object has no attribute 'exec_'
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import sys
 
from PyQt6.QtWidgets import QApplication, QWidget
 
 
class Widget(QWidget):
 
    def __init__(self):
        super().__init__()
 
if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
Цитата Сообщение от Fudthhh Посмотреть сообщение
Можно использовать и старым способом, криминального ничего нет.
У меня не работает без OpenModeFlag. Почему?

AttributeError: type object 'QIODevice' has no attribute 'ReadOnly'
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sys
 
from PyQt6.QtCore import QFile, QIODevice
from PyQt6.QtWidgets import QApplication, QWidget
 
 
class Widget(QWidget):
 
    def __init__(self):
        super().__init__()
 
        path = "assets/text.txt"
        file = QFile(path)
        if not file.open(QIODevice.ReadOnly):
            print("Failed to open the file: " + path)
        file.close()
 
if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec())
1
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,144
Записей в блоге: 243
30.01.2023, 21:57
Цитата Сообщение от Fudthhh Посмотреть сообщение
Не совсем верное утверждение, оба метода существует, но "exec_" считается устаревшим, и возможно в будущих версиях этот метод будет удален.
Я так понял, что на PyQt6 решили не дожидаться и уже удалили "exec_", а на PySide 6.3.1 этот метод всё ещё работает, но выводится предупреждающее сообщение:

DeprecationWarning: 'exec_' will be removed in the future. Use 'exec' instead.
Цитата Сообщение от Fudthhh Посмотреть сообщение
Можно использовать и старым способом, криминального ничего нет.
Опять же, на PyQt6 удалили QIODevice.ReadOnly и сделали QIODevice.OpenModeFlag.ReadOnly, но на PySide 6.3.1 и Qt 6.2.0 C++ оба варианта работают:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import sys
 
from PySide6.QtCore import QFile, QIODevice
from PySide6.QtWidgets import QApplication, QWidget
 
 
class Widget(QWidget):
 
    def __init__(self):
        super().__init__()
 
        path = "assets/text.txt"
        file = QFile(path)
        # if not file.open(QIODevice.OpenModeFlag.ReadOnly):
        if not file.open(QIODevice.ReadOnly):
            print("Failed to open the file: " + path)
        print(file.readAll())
        file.close()
 
if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec())
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
/* Create a .pro file with this content:
QT += core gui widgets
SOURCES += main.cpp
TARGET = app
-------------------------------
Build and run commands for CMD:
> qmake -makefile
> mingw32-make
> "release/app"
*/
 
#ifdef _WIN32
#include <windows.h>
#endif
 
#include <QtCore/QFile>
#include <QtCore/QIODevice>
#include <QtCore/QString>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
 
#include <iostream>
 
class Widget : public QWidget
{
public:
    Widget()
    {
        setWindowTitle("My Title");
        std::cout << std::endl; // flush the console
 
        QString path("assets/text.txt");
        QFile file(path);
        // if (file.open(QIODevice::ReadOnly))
        if (file.open(QIODevice::OpenModeFlag::ReadOnly))
        {
            QString fileContent = file.readAll();
            std::cout << fileContent.toStdString() << std::endl;
        }
        file.close();
    }
};
 
int main(int argc, char *argv[])
{
#ifdef _WIN32
    if (AttachConsole(ATTACH_PARENT_PROCESS))
    {
        freopen("CONOUT$", "w", stdout);
        freopen("CONOUT$", "w", stderr);
    }
#endif
 
    QApplication app(argc, argv);
    Widget w;
    w.show();
    return app.exec();
}
2
290 / 205 / 68
Регистрация: 18.09.2019
Сообщений: 407
Записей в блоге: 58
30.01.2023, 22:37
Ну и, наверное, говоря о различиях PyQt5 и PyQt6, нельзя не упомянуть то, что говорит сам разработчик PyQt Differences Between PyQt6 and PyQt5

In this section we give an overview of the differences between PyQt6 and PyQt5. This is not an exhaustive list and does not go into the detail of the differences between the Qt v6 and Qt v5 APIs.

All named enums are now implemented as a sub-class of the standard Python Enum class. (PyQt5 used IntEnum for scoped enums and a custom type for traditional named enums).

Qt provides the QFlags template class as a type-safe way of using enum values that can be combined as a set of flags. The name of the class is often the plural form of the name of the enum. PyQt5 implements both of these as separate types. PyQt6 instead combines them as a single type, using the name of the enum, as a sub-class of Flag.

Q_CLASSINFO() has been replaced by the pyqtClassInfo() class decorator.

Q_ENUM(), Q_ENUMS(), Q_FLAG() and Q_FLAGS() have been replaced by the pyqtEnum() class decorator.

All exec_() and print_() methods have been removed.

qApp has been removed.

The PYQT_CONFIGURATION dict has been removed.

The Qt module has been removed.

The bindings for the (GPL licensed) Qt classes that implement support for network authorisation have moved out to a separate add-on project PyQt6-NetworkAuth. This means that all of the libraries wrapped by PyQt6 itself are licensed under the LGPL.

pylupdate6 is a completely new pure-Python implementation. It can no longer read a .pro file in order to determine the names of .py files to translate.

Support for Qt’s resource system has been removed (i.e. there is no pyrcc6).

Python v3.6.1 or later is required.

Qt v6 implements a number of functions from Qt v5 that are now marked as being deprecated. These are not supported in PyQt6.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.01.2023, 22:37

PyQT Табуляторы
Народ подскажите как сделать чтобы один и тот же Виджет был сразу на всех табах? Такое возможно вообще? Допустим у меня есть QWEBView, я...

Установка PyQt
Есть такой скрипт: from PyQt5.QtCore import* from PyQt5.QtGui import* import sys class qtWindow(QMainWindow): def...

Лицензия PyQt
На странице https://pypi.org/project/PyQt6/ написано в переводе на русский PyQt6 выпускается под лицензией GPL v3 и под коммерческой...

Работа с PyQt
Вообщем,есть два окна,сначала появляется 1-ое окно и при определенном условии оно должно закрыться,пусть будет нажатая кнопка, и передать...

PyQt и QtDesigner
Никак не могу вкурить как назначать на обработчики событий свои процедуры. вот пример который я нашел #!/usr/bin/python #...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru