├── .phones.sqlite3
├── images
└── phone.gif
├── requirements.txt
├── LICENSE
├── README.chinese.md
├── README.hindi.md
├── README.md
├── README.ru.md
├── gui.py
├── gui_draft.py
└── main.py
/.phones.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BEPb/Phonebook/HEAD/.phones.sqlite3
--------------------------------------------------------------------------------
/images/phone.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BEPb/Phonebook/HEAD/images/phone.gif
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | PyQt5==5.15.1
2 | PyQt5-sip==12.8.1
3 | XlsxWriter==1.3.6
4 | xlrd==1.2.0
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Andrej Marinchenko
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.chinese.md:
--------------------------------------------------------------------------------
1 | # Phonebook
2 |
3 | Your own Phonebook written in python.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Read in other languages: [English](README.md), [हिन्दी](README.hindi.md), [Russian](README.ru.md)
20 |
21 |
22 |
23 | 
24 |
25 |
26 | ##如何安裝和運行
27 | ____
28 | ### 克隆存儲庫
29 |
30 | ```sh
31 | $ cmd
32 | $ git clone https://github.com/BEPb/Browser
33 | $ cd Browser
34 | ```
35 |
36 | ### 安裝必要的包(安裝依賴)
37 | ```sh
38 | $ pip install -r requirements.txt
39 | ```
40 |
41 | ## 用法
42 | 要啟動 GUI:
43 | ```
44 | python3 -m main
45 | ```
46 |
47 | ## 項目發展
48 | 歡迎提出項目開發請求。 對於重大更改,請先打開一個問題,以便
49 | 討論你想改變什麼。
50 | ____
51 |
52 | ## 執照
53 |
54 |
55 | [MIT](LICENSE.txt)
56 |
57 | ____
58 |
59 |
60 |
--------------------------------------------------------------------------------
/README.hindi.md:
--------------------------------------------------------------------------------
1 | # Phonebook
2 |
3 | Your own Phonebook written in python.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Read in other languages: [English](README.md), [Russian](README.ru.md), [中國人](README.chinese.md)
20 |
21 |
22 |
23 | 
24 |
25 |
26 | ## कैसे स्थापित करें और चलाएं
27 | ____
28 | ### रिपॉजिटरी को क्लोन करें
29 |
30 | ```sh
31 | $ cmd
32 | $ git clone https://github.com/BEPb/Browser
33 | $ cd Browser
34 | ```
35 |
36 | ### आवश्यक पैकेज स्थापित करें (निर्भरता स्थापित करें)
37 | ```sh
38 | $ pip install -r requirements.txt
39 |
40 | ```
41 |
42 | ## उपयोग
43 | 要啟動 GUI:
44 | ```
45 | python3 -m main
46 | ```
47 |
48 | ## परियोजना का विकास
49 | परियोजना विकास अनुरोधों का स्वागत है। बड़े बदलावों के लिए, कृपया पहले एक मुद्दा खोलें ताकि
50 | चर्चा करें कि आप क्या बदलना चाहते हैं।
51 | ____
52 |
53 | ## लाइसेंस
54 |
55 | [MIT](LICENSE.txt)
56 |
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Phonebook
2 |
3 | Your own Phonebook written in python.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Read in other languages: [Russian](README.ru.md), [हिन्दी](README.hindi.md), [中國人](README.chinese.md)
19 |
20 |
21 |
22 | 
23 |
24 |
25 |
26 | ## How to install and run
27 | ____
28 | ### Clone the repository
29 |
30 | ```sh
31 | $ cmd
32 | $ git clone https://github.com/BEPb/Phonebook
33 | $ cd Phonebook
34 | ```
35 |
36 | ### Install the necessary packages (Install dependencies)
37 | ```sh
38 | $ pip install -r requirements.txt
39 | ```
40 |
41 | ## Usage
42 | To launch the GUI:
43 | ```
44 | python3 -m main
45 | ```
46 | ## Contributing
47 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
48 | ____
49 |
50 | ## License
51 |
52 |
53 | [MIT](LICENSE.txt)
54 |
55 | ____
56 |
57 |
58 |
--------------------------------------------------------------------------------
/README.ru.md:
--------------------------------------------------------------------------------
1 | # Phonebook
2 |
3 | Ваша собственный телефонный справочник написанный на питоне.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Читать на других языках: [English](README.md), [हिन्दी](README.hindi.md), [中國人](README.chinese.md)
20 |
21 |
22 |
23 | 
24 |
25 |
26 | ## Порядок установки и запуска
27 | ____
28 | ### Клонируем репозиторий (Clone the repository)
29 |
30 | ```sh
31 | $ cmd
32 | $ git clone https://github.com/BEPb/Browser
33 | $ cd Browser
34 | ```
35 |
36 | ### Устанавливаем необходимые пакеты (Install dependencies)
37 | ```sh
38 | $ pip install -r requirements.txt
39 |
40 | ```
41 |
42 | ## Использование
43 | Чтобы запустить графический интерфейс:
44 | ```
45 | python main.py
46 | ```
47 |
48 | ## Развитие проекта
49 | Запросы на развитие проекта приветствуются. Для серьезных изменений, пожалуйста, сначала откройте вопрос, чтобы
50 | обсудить, что вы хотели бы изменить.
51 | ____
52 |
53 | ## Лицензия
54 | [MIT](LICENSE.txt)
55 |
56 |
--------------------------------------------------------------------------------
/gui.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Python 3.9 программа консольного приложения телефонного справочника
4 | Название файла gui.py
5 |
6 | Version: 0.1
7 | Author: Andrej Marinchenko
8 | Date: 2022-04-23
9 | """
10 |
11 | from PyQt5 import QtCore, QtGui, QtWidgets
12 |
13 |
14 | class Ui_MainWindow(object):
15 | def setupUi(self, MainWindow):
16 | MainWindow.setObjectName("MainWindow") # создаем экземпляр объекта главного окна
17 | font = QtGui.QFont() #
18 | font.setFamily("Tahoma") # определяем шрифт
19 | MainWindow.setFont(font) # применяем шрифт для главного окна
20 | MainWindow.setLayoutDirection(QtCore.Qt.LeftToRight) # определяем порядок размещения кнопок слева на право
21 | MainWindow.setLocale(QtCore.QLocale(QtCore.QLocale.Russian, QtCore.QLocale.Russia)) # определяем язык и страну
22 | self.centralwidget = QtWidgets.QWidget(MainWindow)
23 | self.centralwidget.setObjectName("centralwidget")
24 | self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
25 | self.gridLayout.setObjectName("gridLayout") # тип размещения элементов сетка
26 |
27 | self.organization = QtWidgets.QLabel(self.centralwidget)
28 | self.organization.setObjectName("organization")
29 | self.gridLayout.addWidget(self.organization, 1, 1, 1, 1, QtCore.Qt.AlignRight)
30 |
31 |
32 | self.table = QtWidgets.QTableWidget(self.centralwidget)
33 | self.table.setShowGrid(True)
34 | self.table.setObjectName("table")
35 | self.table.setColumnCount(13)
36 | # self.table.setRowCount(1)
37 |
38 |
39 |
40 | item = QtWidgets.QTableWidgetItem()
41 | self.table.setHorizontalHeaderItem(0, item)
42 | item = QtWidgets.QTableWidgetItem()
43 | self.table.setHorizontalHeaderItem(1, item)
44 | item = QtWidgets.QTableWidgetItem()
45 | self.table.setHorizontalHeaderItem(2, item)
46 | item = QtWidgets.QTableWidgetItem()
47 | self.table.setHorizontalHeaderItem(3, item)
48 | item = QtWidgets.QTableWidgetItem()
49 | self.table.setHorizontalHeaderItem(4, item)
50 | item = QtWidgets.QTableWidgetItem()
51 | self.table.setHorizontalHeaderItem(5, item)
52 | item = QtWidgets.QTableWidgetItem()
53 | self.table.setHorizontalHeaderItem(6, item)
54 | item = QtWidgets.QTableWidgetItem()
55 | self.table.setHorizontalHeaderItem(7, item)
56 | item = QtWidgets.QTableWidgetItem()
57 | self.table.setHorizontalHeaderItem(8, item)
58 | item = QtWidgets.QTableWidgetItem()
59 | self.table.setHorizontalHeaderItem(9, item)
60 | item = QtWidgets.QTableWidgetItem()
61 | self.table.setHorizontalHeaderItem(10, item)
62 | item = QtWidgets.QTableWidgetItem()
63 | self.table.setHorizontalHeaderItem(11, item)
64 | item = QtWidgets.QTableWidgetItem()
65 | self.table.setHorizontalHeaderItem(12, item)
66 | item = QtWidgets.QTableWidgetItem()
67 | self.table.setHorizontalHeaderItem(13, item)
68 |
69 | # определяем положение таблицы в сетке
70 | self.gridLayout.addWidget(self.table, 0, 3, 15, 1) # строка=0, колонка=3, отступ строка=10, отступ колонка=1
71 |
72 | # подпись ячейки
73 | self.label_1 = QtWidgets.QLabel(self.centralwidget)
74 | self.label_1.setObjectName("label_1")
75 | self.gridLayout.addWidget(self.label_1, 0, 1, 1, 1)
76 | # ячейка ввода
77 | self.organization = QtWidgets.QLineEdit(self.centralwidget)
78 | self.organization.setObjectName("organization")
79 | self.gridLayout.addWidget(self.organization, 0, 2, 1, 1, QtCore.Qt.AlignLeft)
80 |
81 | # подпись ячейки
82 | self.label_2 = QtWidgets.QLabel(self.centralwidget)
83 | self.label_2.setObjectName("label_2")
84 | self.gridLayout.addWidget(self.label_2, 1, 1, 1, 1)
85 | # ячейка ввода
86 | self.division = QtWidgets.QLineEdit(self.centralwidget)
87 | self.division.setObjectName("division")
88 | self.gridLayout.addWidget(self.division, 1, 2, 1, 1, QtCore.Qt.AlignLeft)
89 |
90 | # подпись ячейки
91 | self.label_3 = QtWidgets.QLabel(self.centralwidget)
92 | self.label_3.setObjectName("label_3")
93 | self.gridLayout.addWidget(self.label_3, 2, 1, 1, 1)
94 | # ячейка ввода
95 | self.subdivision = QtWidgets.QLineEdit(self.centralwidget)
96 | self.subdivision.setObjectName("subdivision")
97 | self.gridLayout.addWidget(self.subdivision, 2, 2, 1, 1, QtCore.Qt.AlignLeft)
98 |
99 | # подпись ячейки
100 | self.label_4 = QtWidgets.QLabel(self.centralwidget)
101 | self.label_4.setObjectName("label_4")
102 | self.gridLayout.addWidget(self.label_4, 3, 1, 1, 1)
103 | # ячейка ввода
104 | self.subdivision_level1 = QtWidgets.QLineEdit(self.centralwidget)
105 | self.subdivision_level1.setObjectName("subdivision_level1")
106 | self.gridLayout.addWidget(self.subdivision_level1, 3, 2, 1, 1, QtCore.Qt.AlignLeft)
107 |
108 | # подпись ячейки
109 | self.label_5 = QtWidgets.QLabel(self.centralwidget)
110 | self.label_5.setObjectName("label_5")
111 | self.gridLayout.addWidget(self.label_5, 4, 1, 1, 1)
112 | # ячейка ввода
113 | self.subdivision_level2 = QtWidgets.QLineEdit(self.centralwidget)
114 | self.subdivision_level2.setObjectName("subdivision_level2")
115 | self.gridLayout.addWidget(self.subdivision_level2, 4, 2, 1, 1, QtCore.Qt.AlignLeft)
116 |
117 | # подпись ячейки
118 | self.label_6 = QtWidgets.QLabel(self.centralwidget)
119 | self.label_6.setObjectName("label_6")
120 | self.gridLayout.addWidget(self.label_6, 5, 1, 1, 1)
121 | # ячейка ввода
122 | self.position = QtWidgets.QLineEdit(self.centralwidget)
123 | self.position.setObjectName("position")
124 | self.gridLayout.addWidget(self.position, 5, 2, 1, 1, QtCore.Qt.AlignLeft)
125 |
126 | # подпись ячейки
127 | self.label_7 = QtWidgets.QLabel(self.centralwidget)
128 | self.label_7.setObjectName("label_7")
129 | self.gridLayout.addWidget(self.label_7, 6, 1, 1, 1)
130 | # ячейка ввода
131 | self.name = QtWidgets.QLineEdit(self.centralwidget)
132 | self.name.setObjectName("name")
133 | self.gridLayout.addWidget(self.name, 6, 2, 1, 1, QtCore.Qt.AlignLeft)
134 |
135 | # подпись ячейки
136 | self.label_8 = QtWidgets.QLabel(self.centralwidget)
137 | self.label_8.setObjectName("label_8")
138 | self.gridLayout.addWidget(self.label_8, 7, 1, 1, 1)
139 | # ячейка ввода
140 | self.family_name = QtWidgets.QLineEdit(self.centralwidget)
141 | self.family_name.setObjectName("family_name")
142 | self.gridLayout.addWidget(self.family_name, 7, 2, 1, 1, QtCore.Qt.AlignLeft)
143 |
144 | # подпись ячейки
145 | self.label_9 = QtWidgets.QLabel(self.centralwidget)
146 | self.label_9.setObjectName("label_9")
147 | self.gridLayout.addWidget(self.label_9, 8, 1, 1, 1)
148 | # ячейка ввода
149 | self.middle_name = QtWidgets.QLineEdit(self.centralwidget)
150 | self.middle_name.setObjectName("middle_name")
151 | self.gridLayout.addWidget(self.middle_name, 8, 2, 1, 1, QtCore.Qt.AlignLeft)
152 |
153 | # подпись ячейки
154 | self.label_10 = QtWidgets.QLabel(self.centralwidget)
155 | self.label_10.setObjectName("label_10")
156 | self.gridLayout.addWidget(self.label_10, 9, 1, 1, 1)
157 | # ячейка ввода
158 | self.work_number = QtWidgets.QLineEdit(self.centralwidget)
159 | self.work_number.setObjectName("work_number")
160 | self.gridLayout.addWidget(self.work_number, 9, 2, 1, 1, QtCore.Qt.AlignLeft)
161 |
162 | # подпись ячейки
163 | self.label_11 = QtWidgets.QLabel(self.centralwidget)
164 | self.label_11.setObjectName("label_11")
165 | self.gridLayout.addWidget(self.label_11, 10, 1, 1, 1)
166 | # ячейка ввода
167 | self.mobile_phone = QtWidgets.QLineEdit(self.centralwidget)
168 | self.mobile_phone.setObjectName("mobile_phone")
169 | self.gridLayout.addWidget(self.mobile_phone, 10, 2, 1, 1, QtCore.Qt.AlignLeft)
170 |
171 | # подпись ячейки
172 | self.label_12 = QtWidgets.QLabel(self.centralwidget)
173 | self.label_12.setObjectName("label_12")
174 | self.gridLayout.addWidget(self.label_12, 11, 1, 1, 1)
175 | # ячейка ввода
176 | self.city_phone = QtWidgets.QLineEdit(self.centralwidget)
177 | self.city_phone.setObjectName("city_phone")
178 | self.gridLayout.addWidget(self.city_phone, 11, 2, 1, 1, QtCore.Qt.AlignLeft)
179 |
180 | # подпись ячейки
181 | self.label_13 = QtWidgets.QLabel(self.centralwidget)
182 | self.label_13.setObjectName("label_13")
183 | self.gridLayout.addWidget(self.label_13, 12, 1, 1, 1)
184 | # ячейка ввода
185 | self.mark = QtWidgets.QLineEdit(self.centralwidget)
186 | self.mark.setObjectName("mark")
187 | self.gridLayout.addWidget(self.mark, 12, 2, 1, 1, QtCore.Qt.AlignLeft)
188 |
189 | # кнопка добавить
190 | self.add = QtWidgets.QPushButton(self.centralwidget)
191 | self.add.setObjectName("add")
192 | self.gridLayout.addWidget(self.add, 14, 0, 1, 3)
193 |
194 | # кнопка удалить
195 | self.remove = QtWidgets.QPushButton(self.centralwidget)
196 | self.remove.setObjectName("remove")
197 | self.gridLayout.addWidget(self.remove, 15, 0, 1, 3)
198 |
199 | # кнопка поиск
200 | self.search = QtWidgets.QPushButton(self.centralwidget)
201 | self.search.setObjectName("search")
202 | self.gridLayout.addWidget(self.search, 16, 0, 1, 3)
203 |
204 | MainWindow.setCentralWidget(self.centralwidget)
205 | self.retranslateUi(MainWindow) # подключаем подписи элементов таблицы
206 | QtCore.QMetaObject.connectSlotsByName(MainWindow)
207 |
208 |
209 |
210 | # прописываем виджеты и действия
211 | exitAction = QtWidgets.QAction('Выход', self)
212 | exitAction.triggered.connect(self.quit_safe)
213 |
214 | saveAction = QtWidgets.QAction('Сохранить', self)
215 | saveAction.triggered.connect(self.save)
216 |
217 | about_programerAction = QtWidgets.QAction('О производителе', self)
218 | about_programerAction.triggered.connect(self.about_programer)
219 |
220 | about_licencAction = QtWidgets.QAction('Лицензия на публикацию программы', self)
221 | about_licencAction.triggered.connect(self.about_licenc)
222 |
223 | excelMenu_import = QtWidgets.QAction('Импорт данных из Excel', self)
224 | excelMenu_import.triggered.connect(self.import_excel)
225 |
226 | excelMenu_export = QtWidgets.QAction('Экспорт в формат Excel', self)
227 | excelMenu_export.triggered.connect(self.export_excel)
228 |
229 | # прописываем менюбар
230 | menubar = self.menuBar()
231 |
232 | fileMenu = menubar.addMenu('Файл') # первая вкладка меню бара (ниже указано его содержание)
233 | fileMenu.addAction(saveAction)
234 | fileMenu.addAction(excelMenu_import)
235 | fileMenu.addAction(excelMenu_export)
236 | fileMenu.addAction(exitAction)
237 |
238 | aboutMenu = menubar.addMenu('О программе') # вторая вкладка меню бара (ниже указано его содержание)
239 | aboutMenu.addAction(about_programerAction)
240 | aboutMenu.addAction(about_licencAction)
241 |
242 | # Кнопки
243 | self.add.clicked.connect(self.add_button)
244 | self.search.clicked.connect(self.search_button)
245 | self.remove.clicked.connect(self.delete_button)
246 |
247 | def retranslateUi(self, MainWindow):
248 | _translate = QtCore.QCoreApplication.translate
249 | MainWindow.setWindowTitle(_translate("MainWindow", "Телефонная книга"))
250 |
251 | # подпись колонок таблицы
252 | item = self.table.horizontalHeaderItem(0)
253 | item.setText(_translate("MainWindow", "Организация"))
254 | item = self.table.horizontalHeaderItem(1)
255 | item.setText(_translate("MainWindow", "Управление"))
256 | item = self.table.horizontalHeaderItem(2)
257 | item.setText(_translate("MainWindow", "Подразделение"))
258 | item = self.table.horizontalHeaderItem(3)
259 | item.setText(_translate("MainWindow", "Подр-е ур.1"))
260 | item = self.table.horizontalHeaderItem(4)
261 | item.setText(_translate("MainWindow", "Подра-е ур.2"))
262 | item = self.table.horizontalHeaderItem(5)
263 | item.setText(_translate("MainWindow", "Должность"))
264 | item = self.table.horizontalHeaderItem(6)
265 | item.setText(_translate("MainWindow", "Имя"))
266 | item = self.table.horizontalHeaderItem(7)
267 | item.setText(_translate("MainWindow", "Отчество"))
268 | item = self.table.horizontalHeaderItem(8)
269 | item.setText(_translate("MainWindow", "Фамилия"))
270 | item = self.table.horizontalHeaderItem(9)
271 | item.setText(_translate("MainWindow", "Внутр. телефон"))
272 | item = self.table.horizontalHeaderItem(10)
273 | item.setText(_translate("MainWindow", "Мобильный телефон"))
274 | item = self.table.horizontalHeaderItem(11)
275 | item.setText(_translate("MainWindow", "Городской телефон"))
276 | item = self.table.horizontalHeaderItem(12)
277 | item.setText(_translate("MainWindow", "Примечание"))
278 | self.table.resizeColumnsToContents() # выравнивание ширины колонок по контенту
279 |
280 | # подписываем ячейки ввода данных
281 | self.label_1.setText(_translate("MainWindow", "Организация"))
282 | self.label_2.setText(_translate("MainWindow", "Управление"))
283 | self.label_3.setText(_translate("MainWindow", "Подразделение"))
284 | self.label_4.setText(_translate("MainWindow", "Подр. ур1"))
285 | self.label_5.setText(_translate("MainWindow", "Подр. ур2"))
286 | self.label_6.setText(_translate("MainWindow", "Должность"))
287 | self.label_7.setText(_translate("MainWindow", "Имя"))
288 | self.label_8.setText(_translate("MainWindow", "Отчество"))
289 | self.label_9.setText(_translate("MainWindow", "Фамилия"))
290 | self.label_10.setText(_translate("MainWindow", "Внутр. телефон"))
291 | self.label_11.setText(_translate("MainWindow", "Моб. телефон"))
292 | self.label_12.setText(_translate("MainWindow", "Гор. телефон"))
293 | self.label_13.setText(_translate("MainWindow", "Примечание"))
294 |
295 | # подпись кнопки
296 | self.add.setText(_translate("MainWindow", "Добавить"))
297 | self.search.setText(_translate("MainWindow", "Поиск"))
298 | self.remove.setText(_translate("MainWindow", "Удалить"))
299 |
300 |
301 |
302 |
303 |
--------------------------------------------------------------------------------
/gui_draft.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | from PyQt5 import QtCore, QtGui, QtWidgets
5 |
6 |
7 | class Ui_MainWindow(object):
8 | def setupUi(self, MainWindow):
9 | MainWindow.setObjectName("MainWindow")
10 | font = QtGui.QFont()
11 | font.setFamily("Tahoma")
12 | MainWindow.setFont(font)
13 | MainWindow.setLayoutDirection(QtCore.Qt.RightToLeft)
14 | MainWindow.setLocale(QtCore.QLocale(QtCore.QLocale.Persian, QtCore.QLocale.Iran))
15 | self.centralwidget = QtWidgets.QWidget(MainWindow)
16 | self.centralwidget.setObjectName("centralwidget")
17 | self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
18 | self.gridLayout.setObjectName("gridLayout")
19 |
20 |
21 | self.division = QtWidgets.QLabel(self.centralwidget)
22 | self.division.setObjectName("Организация")
23 | self.gridLayout.addWidget(self.division, 1, 1, 1, 1)
24 |
25 | self.subdivision = QtWidgets.QLabel(self.centralwidget)
26 | self.subdivision.setObjectName("подразделение")
27 | self.gridLayout.addWidget(self.subdivision, 0, 1, 1, 1)
28 |
29 | self.subdivision_level1 = QtWidgets.QLineEdit(self.centralwidget)
30 | self.subdivision_level1.setObjectName("подразделение ур.1")
31 | self.gridLayout.addWidget(self.subdivision_level1, 0, 0, 1, 1, QtCore.Qt.AlignLeft)
32 |
33 | self.subdivision_level2 = QtWidgets.QLabel(self.centralwidget)
34 | self.subdivision_level2.setObjectName("подразделение ур.2")
35 | self.gridLayout.addWidget(self.subdivision_level2, 3, 1, 1, 1)
36 |
37 | self.label_9 = QtWidgets.QLabel(self.centralwidget)
38 | self.label_9.setObjectName("label_9")
39 | self.gridLayout.addWidget(self.label_9, 4, 1, 1, 1)
40 |
41 | self.phone3 = QtWidgets.QLineEdit(self.centralwidget)
42 | self.phone3.setObjectName("phone3")
43 | self.gridLayout.addWidget(self.phone3, 4, 0, 1, 1, QtCore.Qt.AlignLeft)
44 |
45 | self.label_8 = QtWidgets.QLabel(self.centralwidget)
46 | self.label_8.setEnabled(True)
47 | self.label_8.setObjectName("label_8")
48 | self.gridLayout.addWidget(self.label_8, 5, 1, 1, 1, QtCore.Qt.AlignLeft)
49 |
50 | self.home1 = QtWidgets.QLineEdit(self.centralwidget)
51 | self.home1.setObjectName("home1")
52 | self.gridLayout.addWidget(self.home1, 5, 0, 1, 1, QtCore.Qt.AlignLeft)
53 |
54 | self.home2 = QtWidgets.QLineEdit(self.centralwidget)
55 | self.home2.setObjectName("home2")
56 | self.gridLayout.addWidget(self.home2, 6, 0, 1, 1, QtCore.Qt.AlignLeft)
57 |
58 | self.label_11 = QtWidgets.QLabel(self.centralwidget)
59 | self.label_11.setObjectName("label_11")
60 | self.gridLayout.addWidget(self.label_11, 2, 1, 1, 1)
61 |
62 | self.work_number = QtWidgets.QLineEdit(self.centralwidget)
63 | self.work_number.setObjectName("work_number")
64 | self.gridLayout.addWidget(self.work_number, 7, 0, 1, 1, QtCore.Qt.AlignLeft)
65 |
66 | self.table = QtWidgets.QTableWidget(self.centralwidget)
67 | self.table.setShowGrid(True)
68 | self.table.setObjectName("table")
69 | self.table.setColumnCount(16)
70 | self.table.setRowCount(0)
71 |
72 |
73 | item = QtWidgets.QTableWidgetItem()
74 | self.table.setHorizontalHeaderItem(0, item)
75 | item = QtWidgets.QTableWidgetItem()
76 | self.table.setHorizontalHeaderItem(1, item)
77 | item = QtWidgets.QTableWidgetItem()
78 | self.table.setHorizontalHeaderItem(2, item)
79 | item = QtWidgets.QTableWidgetItem()
80 | self.table.setHorizontalHeaderItem(3, item)
81 | item = QtWidgets.QTableWidgetItem()
82 | self.table.setHorizontalHeaderItem(4, item)
83 | item = QtWidgets.QTableWidgetItem()
84 | self.table.setHorizontalHeaderItem(5, item)
85 | item = QtWidgets.QTableWidgetItem()
86 | self.table.setHorizontalHeaderItem(6, item)
87 | item = QtWidgets.QTableWidgetItem()
88 | self.table.setHorizontalHeaderItem(7, item)
89 | item = QtWidgets.QTableWidgetItem()
90 | self.table.setHorizontalHeaderItem(8, item)
91 | item = QtWidgets.QTableWidgetItem()
92 | self.table.setHorizontalHeaderItem(9, item)
93 | item = QtWidgets.QTableWidgetItem()
94 | self.table.setHorizontalHeaderItem(10, item)
95 | item = QtWidgets.QTableWidgetItem()
96 | self.table.setHorizontalHeaderItem(11, item)
97 | item = QtWidgets.QTableWidgetItem()
98 | self.table.setHorizontalHeaderItem(12, item)
99 | item = QtWidgets.QTableWidgetItem()
100 | self.table.setHorizontalHeaderItem(13, item)
101 |
102 |
103 |
104 | self.gridLayout.addWidget(self.table, 0, 3, 18, 1)
105 | self.label_7 = QtWidgets.QLabel(self.centralwidget)
106 | self.label_7.setObjectName("label_7")
107 | self.gridLayout.addWidget(self.label_7, 6, 1, 1, 1)
108 | self.family = QtWidgets.QLineEdit(self.centralwidget)
109 | self.family.setObjectName("family")
110 | self.gridLayout.addWidget(self.family, 1, 0, 1, 1, QtCore.Qt.AlignLeft)
111 | self.phone1 = QtWidgets.QLineEdit(self.centralwidget)
112 | self.phone1.setObjectName("phone1")
113 | self.gridLayout.addWidget(self.phone1, 2, 0, 1, 1, QtCore.Qt.AlignLeft)
114 | self.label_6 = QtWidgets.QLabel(self.centralwidget)
115 | self.label_6.setObjectName("label_6")
116 | self.gridLayout.addWidget(self.label_6, 7, 1, 1, 1)
117 | self.label_5 = QtWidgets.QLabel(self.centralwidget)
118 | self.label_5.setObjectName("label_5")
119 | self.gridLayout.addWidget(self.label_5, 8, 1, 1, 1)
120 | self.phone2 = QtWidgets.QLineEdit(self.centralwidget)
121 | self.phone2.setObjectName("phone2")
122 | self.gridLayout.addWidget(self.phone2, 3, 0, 1, 1, QtCore.Qt.AlignLeft)
123 | self.website = QtWidgets.QLineEdit(self.centralwidget)
124 | self.website.setObjectName("website")
125 | self.gridLayout.addWidget(self.website, 10, 0, 1, 2)
126 | self.email = QtWidgets.QLineEdit(self.centralwidget)
127 | self.email.setObjectName("email")
128 | self.gridLayout.addWidget(self.email, 11, 0, 1, 2)
129 | self.messager = QtWidgets.QComboBox(self.centralwidget)
130 | self.messager.setMinimumSize(QtCore.QSize(70, 0))
131 | self.messager.setObjectName("messager")
132 | self.messager.addItem("")
133 | self.messager.addItem("")
134 | self.messager.addItem("")
135 | self.messager.addItem("")
136 | self.messager.addItem("")
137 |
138 |
139 | self.gridLayout.addWidget(self.messager, 13, 0, 1, 1)
140 | self.label_2 = QtWidgets.QLabel(self.centralwidget)
141 | self.label_2.setObjectName("label_2")
142 | self.gridLayout.addWidget(self.label_2, 11, 2, 1, 1)
143 | self.remove = QtWidgets.QPushButton(self.centralwidget)
144 | self.remove.setObjectName("remove")
145 | self.gridLayout.addWidget(self.remove, 15, 0, 1, 3)
146 | self.search = QtWidgets.QPushButton(self.centralwidget)
147 | self.search.setObjectName("search")
148 | self.gridLayout.addWidget(self.search, 16, 0, 1, 3)
149 | self.fax = QtWidgets.QLineEdit(self.centralwidget)
150 | self.fax.setObjectName("fax")
151 | self.gridLayout.addWidget(self.fax, 8, 0, 1, 1, QtCore.Qt.AlignLeft)
152 | self.label_4 = QtWidgets.QLabel(self.centralwidget)
153 | self.label_4.setObjectName("label_4")
154 | self.gridLayout.addWidget(self.label_4, 9, 2, 1, 1)
155 | self.workpath_text = QtWidgets.QLabel(self.centralwidget)
156 | self.workpath_text.setLayoutDirection(QtCore.Qt.RightToLeft)
157 | self.workpath_text.setObjectName("workpath_text")
158 | self.gridLayout.addWidget(self.workpath_text, 12, 2, 1, 1)
159 | self.workpath = QtWidgets.QLineEdit(self.centralwidget)
160 | self.workpath.setObjectName("workpath")
161 | self.gridLayout.addWidget(self.workpath, 12, 0, 1, 2)
162 | self.home_path = QtWidgets.QLineEdit(self.centralwidget)
163 | self.home_path.setObjectName("home_path")
164 | self.gridLayout.addWidget(self.home_path, 9, 0, 1, 2)
165 | self.phone_msg = QtWidgets.QLineEdit(self.centralwidget)
166 | self.phone_msg.setObjectName("phone_msg")
167 | self.gridLayout.addWidget(self.phone_msg, 13, 1, 1, 1, QtCore.Qt.AlignLeft)
168 | self.label = QtWidgets.QLabel(self.centralwidget)
169 | self.label.setObjectName("label")
170 | self.gridLayout.addWidget(self.label, 13, 2, 1, 1, QtCore.Qt.AlignLeft)
171 | self.label_3 = QtWidgets.QLabel(self.centralwidget)
172 | self.label_3.setObjectName("label_3")
173 | self.gridLayout.addWidget(self.label_3, 10, 2, 1, 1)
174 | self.export_2 = QtWidgets.QPushButton(self.centralwidget)
175 | self.export_2.setObjectName("export_2")
176 | self.gridLayout.addWidget(self.export_2, 17, 0, 1, 3)
177 | self.add = QtWidgets.QPushButton(self.centralwidget)
178 | self.add.setObjectName("add")
179 | self.gridLayout.addWidget(self.add, 14, 0, 1, 3)
180 | MainWindow.setCentralWidget(self.centralwidget)
181 |
182 | self.retranslateUi(MainWindow)
183 | QtCore.QMetaObject.connectSlotsByName(MainWindow)
184 | #Buttons
185 | self.add.clicked.connect(self.add_button)
186 | self.search.clicked.connect(self.search_button)
187 | self.remove.clicked.connect(self.delete_button)
188 | self.export_2.clicked.connect(self.export)
189 |
190 | #Regex for persion
191 | persian_alpha_codepoints = '\u0621-\u0628\u062A-\u063A\u0641-\u0642\u0644-\u0648\u064E-\u0651\u0655\u067E\u0686\u0698\u06A9\u06AF\u06BE\u06CC'
192 | arabic_numbers_codepoints = '\u0660-\u0669'
193 | additional_arabic_characters_codepoints = '\u0629\u0643\u0649-\u064B\u064D\u06D5'
194 | punctuation_marks_codepoints = '\u060C\u061B\u061F\u0640\u066A\u066B\u066C'
195 | space_codepoints ='\u0020\u2000-\u200F\u2028-\u202F'
196 | persian_num_codepoints = '\u06F0-\u06F9'
197 |
198 | #OnlyInt part
199 | self.only_int = QtCore.QRegExp("[0-9" + persian_num_codepoints + arabic_numbers_codepoints + "]+")
200 | self.only_int_reg = QtGui.QRegExpValidator(self.only_int)
201 | self.home1.setValidator(self.only_int_reg)
202 | self.home2.setValidator(self.only_int_reg)
203 | self.work_number.setValidator(self.only_int_reg)
204 | self.phone1.setValidator(self.only_int_reg)
205 | self.phone2.setValidator(self.only_int_reg)
206 | self.phone3.setValidator(self.only_int_reg)
207 | self.fax.setValidator(self.only_int_reg)
208 | self.phone_msg.setValidator(self.only_int_reg)
209 |
210 | #Only al part
211 | self.only_english = QtCore.QRegExp('[A-Za-z0-9 0-9\\#\+\-\−\_@\.]+')
212 | self.only_persian = QtCore.QRegExp(r"[\s,"+persian_alpha_codepoints+additional_arabic_characters_codepoints
213 | +punctuation_marks_codepoints+space_codepoints+arabic_numbers_codepoints+persian_num_codepoints+r" 0-9\\#\+\-\−\_@\.]+")
214 |
215 | self.only_english_reg = QtGui.QRegExpValidator(self.only_english)
216 | self.only_persian_reg = QtGui.QRegExpValidator(self.only_persian)
217 |
218 | self.website.setValidator(self.only_english_reg)
219 | self.email.setValidator(self.only_english_reg)
220 |
221 | self.subdivision_level1.setValidator(self.only_persian_reg)
222 | self.family.setValidator(self.only_persian_reg)
223 |
224 | self.home_path.setValidator(self.only_persian_reg)
225 | self.workpath.setValidator(self.only_persian_reg)
226 |
227 |
228 | exitAction = QtWidgets.QAction('Выход', self)
229 | exitAction.triggered.connect(self.quit_safe)
230 |
231 | saveAction = QtWidgets.QAction('Сохранить', self)
232 | saveAction.triggered.connect(self.save)
233 |
234 | about_programerAction = QtWidgets.QAction('О производителе', self)
235 | about_programerAction.triggered.connect(self.about_programer)
236 |
237 | about_licencAction = QtWidgets.QAction('Лицензия на публикацию программы', self)
238 | about_licencAction.triggered.connect(self.about_licenc)
239 |
240 | about_licencAction = QtWidgets.QAction('Лицензия на публикацию программы', self)
241 | about_licencAction.triggered.connect(self.about_licenc)
242 |
243 | excelMenu_import = QtWidgets.QAction('Импорт данных из Excel', self)
244 | excelMenu_import.triggered.connect(self.import_excel)
245 |
246 | excelMenu_export = QtWidgets.QAction('Вывод в формате Excel', self)
247 | excelMenu_export.triggered.connect(self.export_excel)
248 |
249 | menubar = self.menuBar()
250 |
251 | fileMenu = menubar.addMenu('сохранить файл')
252 | fileMenu.addAction(saveAction)
253 | fileMenu.addAction(exitAction)
254 |
255 | excelMenu = menubar.addMenu('импорт эксель')
256 | excelMenu.addAction(excelMenu_import)
257 | excelMenu.addAction(excelMenu_export)
258 |
259 | aboutMenu = menubar.addMenu('о программе')
260 | aboutMenu.addAction(about_programerAction)
261 | aboutMenu.addAction(about_licencAction)
262 |
263 | def retranslateUi(self, MainWindow):
264 | _translate = QtCore.QCoreApplication.translate
265 | MainWindow.setWindowTitle(_translate("MainWindow", "Телефонная книга"))
266 | self.division.setText(_translate("MainWindow", "Организация"))
267 | self.subdivision.setText(_translate("MainWindow", "Подразделение"))
268 | # self.subdivision_level1.setText(_translate("MainWindow", "Подразделение ур1"))
269 | self.subdivision_level2.setText(_translate("MainWindow", "Подразделение ур2"))
270 | self.label_9.setText(_translate("MainWindow", "Номер телефона 3"))
271 | self.label_8.setText(_translate("MainWindow", "Номер домашнего телефона
"))
272 | self.label_11.setText(_translate("MainWindow", "телефонный номер 1"))
273 | item = self.table.horizontalHeaderItem(0)
274 | item.setText(_translate("MainWindow", "название"))
275 | item = self.table.horizontalHeaderItem(1)
276 | item.setText(_translate("MainWindow", "фамилия"))
277 | item = self.table.horizontalHeaderItem(2)
278 | item.setText(_translate("MainWindow", "телефонный номер 1"))
279 | item = self.table.horizontalHeaderItem(3)
280 | item.setText(_translate("MainWindow", "телефонный номер 2"))
281 | item = self.table.horizontalHeaderItem(4)
282 | item.setText(_translate("MainWindow", "телефонный номер 3"))
283 | item = self.table.horizontalHeaderItem(5)
284 | item.setText(_translate("MainWindow", "Номер домашнего телефона 1"))
285 | item = self.table.horizontalHeaderItem(6)
286 | item.setText(_translate("MainWindow", "Номер домашнего телефона 2"))
287 | item = self.table.horizontalHeaderItem(7)
288 | item.setText(_translate("MainWindow", "Номер рабочего места"))
289 | item = self.table.horizontalHeaderItem(8)
290 | item.setText(_translate("MainWindow", "текст 8"))
291 | item = self.table.horizontalHeaderItem(9)
292 | item.setText(_translate("MainWindow", "текст 9"))
293 | item = self.table.horizontalHeaderItem(10)
294 | item.setText(_translate("MainWindow", "текст 10"))
295 | item = self.table.horizontalHeaderItem(11)
296 | item.setText(_translate("MainWindow", "текст 11"))
297 | item = self.table.horizontalHeaderItem(12)
298 | item.setText(_translate("MainWindow", "текст 12"))
299 | item = self.table.horizontalHeaderItem(13)
300 | item.setText(_translate("MainWindow", "текст 13"))
301 |
302 | self.label_7.setText(_translate("MainWindow", "Номер домашнего телефона 2"))
303 | self.label_6.setText(_translate("MainWindow", "Номер рабочего места"))
304 | self.label_5.setText(_translate("MainWindow", "факс"))
305 | self.messager.setItemText(0, _translate("MainWindow", "«Эта»"))
306 | self.messager.setItemText(1, _translate("MainWindow", "«Соруш»"))
307 | self.messager.setItemText(2, _translate("MainWindow", "«WhatsApp»"))
308 | self.messager.setItemText(3, _translate("MainWindow", "«Telegram»"))
309 | self.messager.setItemText(4, _translate("MainWindow", "«Другие мессенджеры»"))
310 | self.label_2.setText(_translate("MainWindow", "Эл. адрес"))
311 | self.remove.setText(_translate("MainWindow", "Цель"))
312 | self.search.setText(_translate("MainWindow", "Поиск"))
313 | self.label_4.setText(_translate("MainWindow", "Домашний адрес"))
314 | self.workpath_text.setText(_translate("MainWindow", "рабочий адрес"))
315 | self.label.setText(_translate("MainWindow", "виртуальный номер телефона"))
316 | self.label_3.setText(_translate("MainWindow", "интернет сайт"))
317 | self.export_2.setText(_translate("MainWindow", "Вывод в Excel"))
318 | self.add.setText(_translate("MainWindow", "Добавлять"))
319 | self.all_messager_types = ['«Эта»', '«Соруш»', '«WhatsApp»', '«Telegram»', '«Другие мессенджеры»']
320 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Python 3.9 программа консольного приложения телефонного справочника
5 | Название файла main.py
6 |
7 | Version: 0.1
8 | Author: Andrej Marinchenko
9 | Date: 2022-04-23
10 | """
11 |
12 |
13 | import gui # подключаем свой модуль класс
14 | import sqlite3 as db
15 | import xlsxwriter
16 | import xlrd
17 | from PyQt5 import QtCore, QtWidgets
18 | from PyQt5.QtWidgets import QApplication, QMessageBox, QFileDialog
19 | from PyQt5.QtCore import pyqtSlot, QObject, QThread, pyqtSignal
20 | from sys import argv
21 |
22 |
23 | class load_worker(QObject):
24 | finished = pyqtSignal()
25 | def __init__(self, sql):
26 | super().__init__()
27 | self.sql = sql
28 |
29 | def run(self):
30 | global database_data
31 | database_data = None
32 | database_data = LoadData(self.sql)
33 | self.finished.emit()
34 |
35 |
36 | class delete_worker(QObject):
37 | finished = pyqtSignal()
38 | def __init__(self, target):
39 | super().__init__()
40 | self.target = target
41 |
42 | def run(self):
43 | con = db.connect('.phones.sqlite3')
44 | for index in sorted(self.target.table.selectionModel().selectedRows()):
45 | row = index.row()
46 | sql = "DELETE FROM Phones WHERE name LIKE '%{0}%' AND middle_name LIKE '%{1}%' AND family_name LIKE '%{2}%'".format(
47 | self.target.table.model().data(self.target.table.model().index(row, 6)),
48 | self.target.table.model().data(self.target.table.model().index(row, 7)),
49 | self.target.table.model().data(self.target.table.model().index(row, 8))
50 | )
51 | # print(self.target.table.model().data(self.target.table.model().index(row, 6)))
52 | # print(self.target.table.model().data(self.target.table.model().index(row, 7)))
53 | # print(self.target.table.model().data(self.target.table.model().index(row, 8)))
54 | cur = con.cursor()
55 | cur.execute(sql)
56 | con.commit()
57 |
58 | self.target.clear_table() # очистка таблицы
59 | self.target.load_table('SELECT * FROM Phones') # чтение таблицы
60 |
61 | # класс создания графического приложения
62 | class App(QtWidgets.QMainWindow, gui.Ui_MainWindow): # на входе библиотека виджета и подключенный собств. модуль
63 | def __init__(self, parent=None): # инициализация класса
64 | super(App, self).__init__(parent)
65 | self.setupUi(self)
66 | self.load_table('SELECT * FROM phones')
67 | self.showMaximized()
68 |
69 | # функция сохранения данных
70 | def save(self):
71 | cur = con.cursor()
72 | for i in range(self.table.rowCount()): # перебираем все строки
73 | column = []
74 | for j in range(self.table.columnCount()): # перебираем все колонки
75 | if j != 12:
76 | column.append(self.table.model().data(self.table.model().index(i, j)))
77 | else:
78 | column.append(self.table.cellWidget(i,j).currentText())
79 |
80 | sql = """UPDATE Phones
81 | SET organization = '%s',
82 | division = '%s',
83 | subdivision = '%s',
84 | subdivision_level1 = '%s',
85 | subdivision_level2 = '%s',
86 | position = '%s',
87 | name = '%s',
88 | middle_name = '%s',
89 | family_name = '%s',
90 | work_number = '%s',
91 | mobile_phone = '%s',
92 | city_phone = '%s',
93 | mark = '%s',
94 | WHERE id = %s;""" % tuple(column)
95 | cur.execute(sql)
96 | con.commit()
97 |
98 | def clear_table(self):
99 | self.table.setRowCount(0)
100 |
101 | # функция чтения данных
102 | def load_table(self, sql):
103 | global database_data
104 | database_data = None
105 | self.thread = QThread(self)
106 | self.worker = load_worker(sql)
107 | self.worker.moveToThread(self.thread)
108 | self.thread.started.connect(self.worker.run)
109 | self.worker.finished.connect(self.thread.quit)
110 | self.worker.finished.connect(self.worker.deleteLater)
111 | self.thread.finished.connect(self.thread.deleteLater)
112 | self.thread.start()
113 | self.thread.finished.connect(self.load_table_thread_callback)
114 |
115 | def load_table_thread_callback(self):
116 | global database_data
117 | if database_data == []:
118 | return False
119 |
120 | for row in database_data:
121 | row_pos = self.table.rowCount()
122 | self.table.insertRow(row_pos)
123 | for i, column in enumerate(row, 0):
124 | normal_widget_item = True
125 | item = QtWidgets.QTableWidgetItem(str(column))
126 | # if i == 12:
127 | # item = QtWidgets.QComboBox()
128 | # item.addItems(self.all_messager_types)
129 | # item.setCurrentIndex(self.all_messager_types.index(column))
130 | # normal_widget_item = False
131 | #
132 | if i == 12:
133 | flags = QtCore.Qt.ItemFlags()
134 | flags != QtCore.Qt.ItemIsEnabled
135 | item.setFlags(flags)
136 |
137 | if normal_widget_item:
138 | self.table.setItem(row_pos, i, item)
139 | else:
140 | self.table.setCellWidget(row_pos,i,item)
141 |
142 | self.table.resizeColumnsToContents()
143 |
144 | def error(self, text, title = "Проблема"):
145 | msg = QMessageBox()
146 | msg.setIcon(QMessageBox.Critical)
147 | msg.setText(text)
148 | msg.setWindowTitle("Проблема")
149 | msg.exec_()
150 | del msg
151 |
152 | def info(self, text, title = "Информация"):
153 | msg = QMessageBox()
154 | msg.setIcon(QMessageBox.Information)
155 | msg.setText(text)
156 | msg.setWindowTitle("Информация")
157 | msg.exec_()
158 | del msg
159 |
160 | def question(self,title,text):
161 | buttonReply = QMessageBox.question(self, title, text, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
162 | if buttonReply == QMessageBox.Yes:
163 | del buttonReply
164 | return True
165 | else:
166 | del buttonReply
167 | return False
168 |
169 |
170 | def export_excel(self):
171 | options = QFileDialog.Options()
172 | options |= QFileDialog.DontUseNativeDialog
173 | fileName, _ = QFileDialog.getSaveFileName(self,"Export", "","Xls Files (*.xlsx)", options=options)
174 | if fileName:
175 | workbook = xlsxwriter.Workbook(fileName)
176 | worksheet = workbook.add_worksheet()
177 |
178 | for i in range(self.table.columnCount()):
179 | text = self.table.horizontalHeaderItem(i).text()
180 | worksheet.write(0, i,text)
181 |
182 | for i in range(self.table.columnCount()):
183 | for j in range(self.table.rowCount()):
184 | if i != 12:
185 | text = self.table.item(j, i).text()
186 | else:
187 | text = self.table.cellWidget(j,i).currentText()
188 | # text = self.table.cellWidget(j, i).currentText()
189 | worksheet.write(j + 1, i,text)
190 | workbook.close()
191 | self.info('Вывод успешно создан!')
192 |
193 | def import_excel(self):
194 | options = QFileDialog.Options()
195 | options = QFileDialog.DontUseNativeDialog
196 | user_file, _ = QFileDialog.getOpenFileName(self,"Please select a file", "","Excel File (*.xlsx)", options=options)
197 | if user_file:
198 | wb = xlrd.open_workbook(user_file)
199 | sheet = wb.sheet_by_index(0)
200 |
201 | for i,row in enumerate(range(sheet.nrows)):
202 | if i == 0:
203 | continue
204 | row_data = []
205 | for j,col in enumerate(range(sheet.ncols)):
206 | if j == 12:
207 | continue
208 | row_data.append(sheet.cell_value(row, col))
209 | try:
210 | AddData(row_data)
211 | self.load_table('SELECT * FROM Phones')
212 | self.info('Информация введена успешно!')
213 |
214 | except db.IntegrityError:
215 | self.error('Пользователь {0} доступен!'.format(i))
216 |
217 | except db.ProgrammingError:
218 | self.error('Файл Excel был изменен. Пользователь {0} не добавлен в базу данных.'.format(i))
219 |
220 | def quit_safe(self):
221 | self.save()
222 | exit(0)
223 |
224 | def closeEvent(self, event):
225 | self.quit_safe()
226 | event.accept()
227 |
228 | def about_programer(self):
229 | self.info("Эта программа была создана Андреем Маринченко. \n Вы можете использовать адрес электронной почты "
230 | "andrej.marinchenko@gmail.com чтобы связаться")
231 |
232 | def about_licenc(self):
233 | self.info('Эта программа выпущена под лицензией GPL версии 3.')
234 |
235 | def reset_textboxs(self):
236 | self.clear_table()
237 | self.load_table('SELECT * FROM phones')
238 | self.organization.setText("")
239 | self.division.setText("")
240 | self.subdivision.setText("")
241 | self.subdivision_level1.setText("")
242 | self.subdivision_level2.setText("")
243 | self.position.setText("")
244 | self.name.setText("")
245 | self.family_name.setText("")
246 | self.middle_name.setText("")
247 | self.work_number.setText("")
248 | self.mobile_phone.setText("")
249 | self.city_phone.setText("")
250 | self.mark.setText("")
251 |
252 | # функция добавления данных в таблицу
253 | @pyqtSlot()
254 | def add_button(self):
255 | datas = {
256 | 'organization' : self.organization.text(),
257 | 'division' : self.division.text(),
258 | 'subdivision' : self.subdivision.text(),
259 | 'subdivision_level1' : self.subdivision_level1.text(),
260 | 'subdivision_level2' : self.subdivision_level2.text(),
261 | 'position' : self.position.text(),
262 | 'name' : self.name.text(),
263 | 'family_name' : self.family_name.text(),
264 | 'middle_name' : self.middle_name.text(),
265 | 'work_number' : self.work_number.text(),
266 | 'mobile_phone' : self.mobile_phone.text(),
267 | 'city_phone' : self.city_phone.text(),
268 | 'mark' : self.mark.text()
269 | }
270 | if datas['name'] and datas['family_name']:
271 | try:
272 | AddData(list(datas.values()))
273 | self.reset_textboxs()
274 | row_pos = self.table.rowCount()
275 | self.table.insertRow(row_pos)
276 | for i, column in enumerate(datas.values(), 0):
277 | normal_widget_item = True
278 | item = QtWidgets.QTableWidgetItem(str(column))
279 | # if i == 12:
280 | # item = QtWidgets.QComboBox()
281 | # item.addItems(self.all_messager_types)
282 | # item.setCurrentIndex(self.all_messager_types.index(column))
283 | # normal_widget_item = False
284 |
285 | if i == 12:
286 | flags = QtCore.Qt.ItemFlags()
287 | flags != QtCore.Qt.ItemIsEnabled
288 | item.setFlags(flags)
289 |
290 | if normal_widget_item:
291 | self.table.setItem(row_pos, i, item)
292 | else:
293 | self.table.setCellWidget(row_pos, i, item)
294 |
295 | self.table.resizeColumnsToContents()
296 | except db.IntegrityError:
297 | self.error('Необходимая информация доступна в базе данных')
298 | else:
299 | self.error('Пожалуйста, заполните имя и фамилию')
300 |
301 | # функция поиска в каждой ячейке
302 | @pyqtSlot()
303 | def search_button(self):
304 | datas = {
305 | 'organization' : self.organization.text(),
306 | 'division' : self.division.text(),
307 | 'subdivision' : self.subdivision.text(),
308 | 'subdivision_level1' : self.subdivision_level1.text(),
309 | 'subdivision_level2' : self.subdivision_level2.text(),
310 | 'position' : self.position.text(),
311 | 'name' : self.name.text(),
312 | 'family_name' : self.family_name.text(),
313 | 'middle_name' : self.middle_name.text(),
314 | 'work_number' : self.work_number.text(),
315 | 'mobile_phone' : self.mobile_phone.text(),
316 | 'city_phone' : self.city_phone.text(),
317 | 'mark' : self.mark.text()
318 | }
319 | sql = """
320 | SELECT * FROM Phones WHERE
321 | organization LIKE '%{0}%' AND
322 | division LIKE '%{1}%' AND
323 | subdivision LIKE '%{2}%' AND
324 | subdivision_level1 LIKE '%{3}%' AND
325 | subdivision_level2 LIKE '%{4}%' AND
326 | position LIKE '%{5}%' AND
327 | name LIKE '%{6}%' AND
328 | family_name LIKE '%{7}%' AND
329 | middle_name LIKE '%{8}%' AND
330 | work_number LIKE '%{9}%' AND
331 | mobile_phone LIKE '%{10}%' AND
332 | city_phone LIKE '%{11}%' AND
333 | mark LIKE '%{12}%'
334 | """.format(
335 | datas['organization'],
336 | datas['division'],
337 | datas['subdivision'],
338 | datas['subdivision_level1'],
339 | datas['subdivision_level2'],
340 | datas['position'],
341 | datas['name'],
342 | datas['family_name'],
343 | datas['middle_name'],
344 | datas['work_number'],
345 | datas['mobile_phone'],
346 | datas['city_phone'],
347 | datas['mark']
348 | )
349 | self.clear_table()
350 | if self.load_table(sql) == False:
351 | self.error("Ошибка чтения")
352 |
353 | # функция удаления строки данных
354 | @pyqtSlot()
355 | def delete_button(self):
356 | if self.table.selectionModel().selectedRows() == []: # если строка данных не выбрана
357 | self.error("Пожалуйста, выберите пользователя для удаления")
358 | return False
359 |
360 | if self.question("Удалить пользователя", "Уверены ли вы?"): # окно подтверждения удаления строки пользователя
361 |
362 | self.del_thread = QThread(self)
363 | self.worker = delete_worker(self)
364 | self.worker.moveToThread(self.del_thread)
365 | self.del_thread.started.connect(self.worker.run)
366 | self.worker.finished.connect(self.thread.quit)
367 | self.worker.finished.connect(self.worker.deleteLater)
368 | self.del_thread.finished.connect(self.del_thread.deleteLater)
369 | self.del_thread.start()
370 |
371 | @pyqtSlot()
372 | def export(self):
373 | self.export_excel()
374 |
375 | # функция создания таблицы данных телефонного справочника
376 | def CreateTable():
377 | global con # глобальная переменная
378 | cur = con.cursor() # курсор подключения к базе данных
379 | cur.execute('''
380 | CREATE TABLE IF NOT EXISTS `phones`(
381 | organization TEXT,
382 | division TEXT,
383 | subdivision TEXT,
384 | subdivision_level1 TEXT,
385 | subdivision_level2 TEXT,
386 | position TEXT,
387 | name TEXT,
388 | family_name TEXT,
389 | middle_name TEXT,
390 | work_number TEXT,
391 | mobile_phone TEXT,
392 | city_phone TEXT,
393 | mark TEXT,
394 | id INTEGER PRIMARY KEY AUTOINCREMENT
395 | )
396 | ''')
397 | return True # создание базы данных успешно
398 |
399 | # функция чтения базы данных
400 | def LoadData(sql):
401 | con = db.connect('.phones.sqlite3') # глобальная переменная
402 | cur = con.cursor()
403 | cur.execute(sql)
404 | return cur.fetchall()
405 |
406 | # функция добавления данных в базу
407 | def AddData(values):
408 | cur = con.cursor()
409 | cur.execute('''
410 | INSERT INTO `phones`(organization, division, subdivision, subdivision_level1, subdivision_level2, position, name, family_name, middle_name, work_number, mobile_phone, city_phone, mark)
411 | VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)
412 | ''',values)
413 | con.commit()
414 | return True
415 |
416 | # главная функция
417 | def main():
418 | global con, mainWindow # определяем глобальные переменные
419 | con = db.connect('.phones.sqlite3') # подключение к базе данных
420 | CreateTable() # создание таблицы (определены все колонки, на выходе истина)
421 | mainApp = QApplication(argv) # главное окно
422 | mainWindow = App() #
423 | mainApp.exec_() #
424 | con.close() #
425 |
426 | # проверка на запуск главной программы
427 | if __name__ == "__main__" : main()
428 |
--------------------------------------------------------------------------------