Файл: Предметная область.docx

ВУЗ: Не указан

Категория: Реферат

Дисциплина: Не указана

Добавлен: 30.10.2023

Просмотров: 27

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.


self.channels_telegram = QtWidgets.QListWidget(self)

self.channels_telegram.setObjectName("channels_telegram")

self.channels_telegram.setIconSize(QSize(32,32))

self.channels_telegram.setFixedSize(200,340)

self.channels_telegram.itemClicked.connect(self.item_changed_telegram_channels)

self.wgt_us_chan = QtWidgets.QWidget()

self.users_channels = QtWidgets.QVBoxLayout(self)

self.users_channels.addWidget(self.users_telegram)

self.users_channels.addWidget(self.channels_telegram)

self.wgt_us_chan.setLayout(self.users_channels)

self.item_users_channels = QListWidgetItem(self.telegram_list)

self.item_users_channels.setSizeHint(self.wgt_us_chan.sizeHint())

self.telegram_list.setItemWidget(self.item_users_channels, self.wgt_us_chan)

self.telegram_connect = QtWidgets.QPushButton("Войти в Telegram!", self)

self.telegram_connect.setFixedSize(180, 30)

self.telegram_connect.clicked.connect(self.clicked_chats_telegram)

self.wgt_telegram = QtWidgets.QWidget()

self.layout_users_telegram = QtWidgets.QVBoxLayout(self)

self.layout_users_telegram.addWidget(self.telegram_connect)

self.wgt_telegram.setLayout(self.layout_users_telegram)

self.item_telegram = QListWidgetItem(self.users_telegram)

self.item_telegram.setSizeHint(self.wgt_telegram.sizeHint())

self.users_telegram.setItemWidget(self.item_telegram, self.wgt_telegram)

self.tab_chats.addTab(self.telegram_list, "Telegram")
Листинг 2 – Динамическое создание объектов
Как видно из листинга 2 сначала создается виджет QGridLayout, который позволяет нам удобно расположить объекты в приложении. Далее создается виджет QListWidget, в котором будут располагаться списки контактов и каналов, у виджета задается фиксированный размер, чтобы он не растягивался по всему окну. Следующим шагом создается два отдельных QListWidget, в которых по отдельности расположатся спикски контактов и каналов, эти списки помещаются в виджет QVBoxLayout, чтобы расположить их в QListWidget, который создавался до этого. Потом соответственно QListWidget с готовыми списками, добавляется в QGridLayout, для отображения на форме приложения.

На рисунке 1 можно увидеть как расположились объекты. Но в данный момент используется стандартный интерфейс, что не выглядит визуально привлекательно и пользователь может не заинтересоваться нашим приложением. Эту проблему можно решить с помощью инструмента QSS[2].


Рисунок 1 – Вид приложения со стандартным интерфейсом
2.2 Графическая составляющая приложения
Ниже приведен листинг 3, который задает характеристики заднего фона, вкладок, кнопок, текстовых редакторов, списков виджетов, а также различные события при наведение курсора на компонет и нажатия на него.
QWidget

{

color: #b1b1b1;

background-color: #323232;

}

QWidget:item:hover

{

background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #ca0619);

color: #000000;

}

QWidget:item:selected

{

background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);


}

QPushButton

{

color: #b1b1b1;

background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646);

border-width: 1px;

border-color: #1e1e1e;

border-style: solid;

border-radius: 6;

padding: 3px;

font-size: 12px;

padding-left: 5px;

padding-right: 5px;

}

QPushButton:pressed

{

background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0

#2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525);

}

QPushButton:hover

{

border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);

}

QTextEdit:focus

{

border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);

}

QTextEdit

{

background-color: #242424;

}
Листинг 3 – задание стилей для виджетов
В листинге 3 задаются стили для объектов, а также псевдоклассы, когда происходят различные события с этими объектами. В данном листинге можно видеть что, для компонента item задается псевдокласс hover, который обрабатывает события наведения курсора на объект, а также задаются стили на событие, когда нажата кнопка.

Как видим на рисунке 2, используя для виджетов инструмент QSS, приложение стало выглядеть визуально привлекательно, у такого приложения уже будет больше спрос у пользователей[4].


Рисунок 2 – Вид приложения с использованием инструмента QSS


    1. Логическая составляющая приложения


Когда пользователь пытается зайти в официальный клиент «Telegram» или «ВКонтакте» перед ним появляется поля, куда он может ввести свои данные для авторизации. Для того чтобы в приложение была возможность для авторизации, был использован принцип объектно-ориентированного программирования. Созданы два класса, которые передавали данные для авторизации пользователя в определенные функции главного класса. На листинге 4 продемонстрирована функция, которая позволяет авторизоваться пользователю в «Telegram»:
def connect_telegram(self):

if self.flag_telegram == False:

if len(self.login_telegram) and len(self.phone_telegram):

self.client=TelegramClient(str(self.login_telegram), api_id,api_hash)

self.client.connect()

if not self.client.is_user_authorized():

self.client.send_code_request(self.phone_telegram)

self.client.sign_in(self.phone_telegram,input('Enter the code:)

self.result1=self.client(GetDialogsRequest(offset_date=None,offset_id=0, offset_peer = InputPeerEmpty(),limit = 200))

self.flag_telegram = True

self.user.extend(self.result1.users)

self.channel.extend(self.result1.chats)

if self.flag_photo_telegram == False:

try:

for user_value in range(0, len(self.user), 1):

users = self.user[user_value]

self.client.download_profile_photo(users)

for channels_value in range(0,len(self.channel), 1):



channels = self.channel[channels_value]

self.client.download_profile_photo(channels)

except ValueError:

pass

except TimeoutError:

pass

else:

self.timer_autoriziting_telegram.stop()

self.telegram_contact()

self.channels_connect()
Листинг 4 – Авторизация в «Telegram»
В описанном листинге выше, сначала принимаются данные с класса авторизации, которые передают телефон и логин пользователя. Если пользователь авторизуются в данном приложении, в канале «Telegram» впервые, то на телефон придет сообщение с кодом для авторизации. Когда авторизации прошла успешно, происходит загрузка сообщений и фотографий контактов и каналов[8].

После авторизации надо отобразить контакты пользователя и каналы. На листинге 5 продемонстрированы эти функции.
def telegram_contact(self):

self.users_telegram.clear()

for user_value in range(0, len(self.user), 1):

users = self.user[user_value]

if users.last_name!=None:

user_n = str(users.first_name) + " " + str(users.last_name)

self.listItem = QListWidgetItem(user_n)

else:

user_n = str(users.first_name)

self.listItem = QListWidgetItem(user_n)

if users.username!=None:

self.listItem.setIcon(QIcon(str(users.username) + ".jpg"))

else:

self.listItem.setIcon(QIcon(str(users.first_name) + ".jpg"))

self.users_telegram.addItem(self.listItem)

self.users_telegram.sortItems()

self.users_telegram.show()

def channels_connect(self):

self.channels_telegram.clear()

for channels_value in range(0,len(self.channel), 1):

channels = self.channel[channels_value]

self.listItem = QListWidgetItem(channels.title)

self.listItem.setIcon(QIcon(str(channels.username)+".jpg)

self.channels_telegram.addItem(self.listItem)

self.channels_telegram.sortItems()

self.channels_telegram.show()
Листинг 5 – Отображение контактов и каналов «Telegram»
В данных функциях загружаются контакты, беседы и каналы в компонент QListWidget, для отображения фотографий используется компонент QIcon, также с помощью метода sortItems все данные в QListWidget сортируется по алфавиту, что позволяет пользователю быстро найти нужным ему контакт, канал или беседу[9].

При выборе нужного пункта в списках, происходит загрузка сообщений, для того что обновлять сообщения используется таймер. В приложения используется всего один таймер для обновления сообщений в контактах, каналах и беседах, потому что при использовании нескольких таймеров приложения начинает тормозить и им становится невозможно пользоваться. Для того чтобы сообщения обновляясь в определенном месте, используются логические переменные, так называемые флаги, которые могут принимать всего два значения – True и False. Например, если пользователь выбирает контакт из «Telegram», то ответственный за контакты флаг принимает значение True, а все остальные False. Функция, реализующая обновления сообщений в «Telegram» представленная на листинге 6.

def message_telgram(self):

login_telegram = ""

users_telegram = ""

if self.flag_telegram_message == True:

self.message_telegram.clear()

self.message_telegram.setVisible(True)

self.message_telegram.setReadOnly(True)

for user_val in range(0,self.users_telegram.count(),1):

users = self.user[user_val]

log_tl = str(users.first_name) + " " + str(users.last_name)

if(self.tabBar.tabText(self.tab_message.currentIndex())==str(users.firs t_name)) or (self.tabBar.tabText(self.tab_message.currentIndex())==log_tl) or (self.tabBar.tabText(self.tab_message.currentIndex())==str(users.username)):

result=self.client(GetHistoryRequest(users,limit=20000000,

offset_date=None,offset_id=0,max_id=0,min_id=0,add_offset=0))

try:

message = result.messages

for message_value in range(0, len(message), 1):

messages = message[message_value]

if (self.my_self.id == messages.from_id):

if self.my_self.last_name == None:

login_telegram = str(self.my_self.first_name)

else:

login_telegram=str(self.my_self.first_name)

" "+str(self.my_self.last_name)

cursor=QTextCursor(self.message_telegram.document())

cursor.insertHtml(""+""+login_telegram+""+"
"+str(messages.date) +"
"+str(messages.message) +"

"+"
")

self.message_telegram.moveCursor(QtGui.QTextCursor.End)

else:

if users.last_name == None:

users_telegram=str(users.first_name)

else:

users_telegram=str(users.first_name)+

" "+str(users.last_name)

cursor=QTextCursor(self.message_telegram.document())

cursor.insertHtml(""+""+users_telegram+""+"
"+str(messages.date) + "
" + str(messages.message) + "

"+"
")

self.message_telegram.moveCursor(QtGui.QTextCursor.End)

except ValueError:

pass

except TimeoutError:

pass

except MemoryError:

pass

except OverflowError:

pass
Листинг 6 – Обновление сообщений «Telegram»
В данной функции сначала определяется, какой выбран контакт или канал, потом этот контакт сравнивается с теми контактами, которые загрузились при авторизации, если контакты совпали, то вызывается метод, который загружает сообщения с выбранным контактом. Далее происходит разделение сообщений на те, которые относятся к пользователю и которые относятся к выбранному контакту и происходит форматирование вывода сообщения c помощью языка разметки html. Процесс обновления сообщений в функции происходит следующим образом: сначала очищается все сообщения, которые вывелись, а потом снова вызывается метод для получения сообщений, так как в таймере задается маленький промежуток обновления, то пользователь не замечает очищения сообщений.

Для обновления сообщений в «ВКонтакте» используется метод LongPoll – это метод получает мгновенный ответ с сервера, то есть не надо будет каждый раз очищать старые сообщения и снова вызывать метод для их получения, сообщения будут отображаться по мере их поступления. Данный метод использовался в функции представленной на листинге 7.
def update_message(self):

for event in self.longpoll.listen():

if event.type == VkEventType.MESSAGE_NEW:

user = self.vk.users.get(user_ids = event.user_id)

user_vk = user[0].get('first_name') + " " + user[0].get('last_name')


if event.from_chat:

chats_vk = self.vk.messages.getChat(chat_id = event.chat_id)

chats_vk_title = chats_vk.get('title')

if self.tabBar.tabText(self.tab_message.currentIndex())==chats_vk_title:

time = event.timestamp

mes = str(event.text)

data=datetime.datetime.fromtimestamp(int(time)).strftime(

'%Y-%m-%d %H:%M:%S')

user_chat=self.vk.users.get(user_ids=event.user_id)

user_vk_chat=user[0].get('first_name')+" "+ user[0].get('last_name')

self.chats_vk_message.append(""+""+user_vk_chat+"" + " " +str(data) + "
" + mes + "

"+"
")

self.chats_vk_message.moveCursor(QtGui.QTextCursor.End)

if self.tabBar.tabText(self.tab_message.currentIndex())==user_vk:

if event.from_me:

time = event.timestamp

mes = str(event.text)

data=datetime.datetime.fromtimestamp(int(time)).strftime

('%Y-%m-%d %H:%M:%S')

self.vk_message.append(""+ ""+self.my_self_vk+

"
" + " "+str(data) + "
" + mes + "

"+"
")

self.vk_message.moveCursor(QtGui.QTextCursor.End)

elif event.to_me:

time = event.timestamp

mes = str(event.text)

data=datetime.datetime.fromtimestamp(int(time)).strftime

('%Y-%m-%d %H:%M:%S')

self.vk_message.append(""+""+user_vk+""+" "+str(data)+"
"+mes+"

"+"
")

self.vk_message.moveCursor(QtGui.QTextCursor.End)
Листинг 7 – Обновление сообщений в «ВКонтакте»
В приложение также есть возможность обмениваться сообщениями, но не с одним контактом из одного клиента, а сразу с несколькими и из разных клиентов, эта функция приложения реализована с помощью компонента QTabWidget. Функции для отправки сообщений в «Telegram», представлена на листинге 8:
def telegram_send(self):

if (self.flag_telegram_message == True):

if (len(self.message_text.toPlainText())):

for user_val1 in range(0,self.users_telegram.count(),1):

users = self.user[user_val1]

log_tl = str(users.first_name) + " " + str(users.last_name)

if(self.tabBar.tabText(self.tab_message.currentIndex())==str(users.first_name))or(self.tabBar.tabText(self.tab_message.currentIndex())==log_tl)or(self.tabBar.tabText(self.tab_message.currentIndex())==str(users.username)):

self.client.send_message(users, self.message_text.toPlainText())

self.message_text.clear()

self.timer_message_telegram.start(5000)
Листинг 8 – Отправка сообщений в «Telegram»
В данной функции тоже используют флаги для определения, какому контакту, каналу или в какую беседу хочет пользователь отправить сообщения, чтобы не произошло ошибки, и сообщение не отправилось в другой место, имя контакта, или название беседы берется с названия вкладки, если контакт с «Telegram», то полученного имя хватает. В случае с «ВКонтакте» нужно определить еще id выбранного контакта, если сообщение отправляется в беседу в «ВКонтакте», то к полученному id беседы прибавляется еще два миллиарда.

ЗАКЛЮЧЕНИЕ

В данном курсовом проекте мной были решены следующие задачи:

  1. Анализ социальных сетей и выбор самых популярных для использования в приложении.

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

  3. Изучение высокоуровневого языка программирования Python.

  4. Изучение среды разработки PyQt.

  5. Ознакомление с механизм QSS, позволяющий настраивать внешний вид виджетов библиотеки Qt.