├── (encrypted)marlon_brando.wav ├── README.md ├── __pycache__ ├── home_ui.cpython-34.pyc ├── image_retrieve.cpython-34.pyc ├── imageselect.cpython-34.pyc ├── login.cpython-34.pyc ├── main_window_ui.cpython-34.pyc ├── main_window_ui.cpython-35.pyc ├── recovery_ui.cpython-34.pyc ├── registration_2_ui.cpython-34.pyc └── registration_ui.cpython-34.pyc ├── database └── Dump20170319.sql ├── dbimages ├── 1.png ├── 10.png ├── 11.png ├── 12.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png └── 9.png ├── filesample.py ├── home_ui.py ├── home_ui.pyc ├── image_retrieve.py ├── image_retrieve.pyc ├── image_store.py ├── imageselect.py ├── imageselect.pyc ├── login.py ├── main.py ├── main_window_ui.py ├── marlon_brando.wav ├── recovery_ui.py ├── recovery_ui.pyc ├── registration_2_ui.py ├── registration_2_ui.pyc ├── registration_ui.py ├── registration_ui.pyc ├── requirements └── requirements.txt ├── screenshots ├── home.JPG ├── image selection.JPG ├── login.JPG ├── main window.JPG ├── registration (step 1 of 2).JPG └── registration (step 2 of 2).JPG ├── send_mail.py └── test └── imageselect scroll test.txt /(encrypted)marlon_brando.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/(encrypted)marlon_brando.wav -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-with-File-Encryption 2 | 3 | The basic foundation of the project is based on an IEEE paper: "Persuasive Cued Click-Points: Design, implementation, and 4 | evaluation of a knowledge-based authentication mechanism" published by Sonia Chiasson,Member, IEEE,Elizabeth Stobert, Alain 5 | Forget, Robert Biddle,Member, IEEE and P. C. van Oorschot,Member, IEEE. 6 | A graphical password authentication system works by having the user select the images, in a specific order. The Persuasive 7 | Technology guides and encourages the user to select stronger passwords (i.e. click-points), but not entirely impose system 8 | generated passwords. The proposed system consists of two modules; user registration and user login. The registration phase, in 9 | which user registers a unique username and the graphical password in the database, is followed by user login phase. During login, 10 | the user is asked to provide the username and correct graphical password. Upon successful verification of the user profile from 11 | the database, the user is now able to encrypt/decrypt his files. The cryptographic algorithm used to provide security to the 12 | files is the AES encryption, where the 16-bit key for cipher is generated from the SHA-256 hashing algorithm implemented on the 13 | user click-points. 14 | 15 | 16 | ### Application Screenshots 17 | 18 | [![html dark](https://github.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/blob/master/screenshots/main%20window.JPG)] 19 | [![html dark](https://github.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/blob/master/screenshots/login.JPG)] 20 | [![html dark](https://github.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/blob/master/screenshots/registration%20(step%201%20of%202).JPG)] 21 | [![html dark](https://github.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/blob/master/screenshots/registration%20(step%202%20of%202).JPG)] 22 | [![html dark](https://github.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/blob/master/screenshots/image%20selection.JPG)] 23 | [![html dark](https://github.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/blob/master/screenshots/home.JPG)] 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /__pycache__/home_ui.cpython-34.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/__pycache__/home_ui.cpython-34.pyc -------------------------------------------------------------------------------- /__pycache__/image_retrieve.cpython-34.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/__pycache__/image_retrieve.cpython-34.pyc -------------------------------------------------------------------------------- /__pycache__/imageselect.cpython-34.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/__pycache__/imageselect.cpython-34.pyc -------------------------------------------------------------------------------- /__pycache__/login.cpython-34.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/__pycache__/login.cpython-34.pyc -------------------------------------------------------------------------------- /__pycache__/main_window_ui.cpython-34.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/__pycache__/main_window_ui.cpython-34.pyc -------------------------------------------------------------------------------- /__pycache__/main_window_ui.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/__pycache__/main_window_ui.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/recovery_ui.cpython-34.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/__pycache__/recovery_ui.cpython-34.pyc -------------------------------------------------------------------------------- /__pycache__/registration_2_ui.cpython-34.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/__pycache__/registration_2_ui.cpython-34.pyc -------------------------------------------------------------------------------- /__pycache__/registration_ui.cpython-34.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/__pycache__/registration_ui.cpython-34.pyc -------------------------------------------------------------------------------- /database/Dump20170319.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/database/Dump20170319.sql -------------------------------------------------------------------------------- /dbimages/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/1.png -------------------------------------------------------------------------------- /dbimages/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/10.png -------------------------------------------------------------------------------- /dbimages/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/11.png -------------------------------------------------------------------------------- /dbimages/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/12.png -------------------------------------------------------------------------------- /dbimages/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/2.png -------------------------------------------------------------------------------- /dbimages/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/3.png -------------------------------------------------------------------------------- /dbimages/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/4.png -------------------------------------------------------------------------------- /dbimages/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/5.png -------------------------------------------------------------------------------- /dbimages/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/6.png -------------------------------------------------------------------------------- /dbimages/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/7.png -------------------------------------------------------------------------------- /dbimages/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/8.png -------------------------------------------------------------------------------- /dbimages/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/dbimages/9.png -------------------------------------------------------------------------------- /filesample.py: -------------------------------------------------------------------------------- 1 | 2 | # -*- coding: utf-8 -*- 3 | 4 | # Form implementation generated from reading ui file 'registration_2.ui' 5 | # 6 | # Created by: PyQt5 UI code generator 5.5 7 | # 8 | # WARNING! All changes made in this file will be lost! 9 | 10 | from PyQt4 import QtCore, QtGui 11 | from PyQt4.QtGui import QApplication, QDialog, QWidget, QMainWindow 12 | import sys 13 | from random import * 14 | import json 15 | from mysql.connector import Error, MySQLConnection 16 | import mysql.connector 17 | 18 | 19 | try: 20 | _fromUtf8 = QtCore.QString.fromUtf8 21 | except AttributeError: 22 | def _fromUtf8(s): 23 | return s 24 | 25 | try: 26 | _encoding = QtGui.QApplication.UnicodeUTF8 27 | def _translate(context, text, disambig): 28 | return QtGui.QApplication.translate(context, text, disambig, _encoding) 29 | except AttributeError: 30 | def _translate(context, text, disambig): 31 | return QtGui.QApplication.translate(context, text, disambig) 32 | 33 | class Ui_Registration_2(QMainWindow): 34 | ax=randint(0,240) #generating random values for button 1 and storing final coodinate positions 35 | ay=randint(0,215) 36 | posax = 20+ax 37 | posay = 170+ay 38 | 39 | bx=randint(0,240) #generating random values for button 2 and storing final coodinate positions 40 | by=randint(0,215) 41 | posbx = 320+bx 42 | posby = 170+by 43 | 44 | cx=randint(0,540) #generating random values for button 3 and storing final coodinate positions 45 | cy=randint(0,65) 46 | poscx = 20+cx 47 | poscy = 445+cy 48 | 49 | imagenum = 0 #nth image in a queue 50 | tvalue = 40 #tolerance value 51 | 52 | 53 | def __init__(self): 54 | QMainWindow.__init__(self) 55 | self.setupUi(self) 56 | 57 | 58 | def setupUi(self, Registration_2): 59 | Registration_2.setObjectName("Registration_2") 60 | Registration_2.resize(800, 600) 61 | Registration_2.setMinimumSize(QtCore.QSize(800, 600)) 62 | Registration_2.setMaximumSize(QtCore.QSize(800, 600)) 63 | self.databaseRadio = QtGui.QRadioButton(Registration_2) 64 | self.databaseRadio.setGeometry(QtCore.QRect(40, 80, 261, 17)) 65 | font = QtGui.QFont() 66 | font.setPointSize(10) 67 | self.databaseRadio.setFont(font) 68 | self.databaseRadio.setObjectName("databaseRadio") 69 | self.galleryRadio = QtGui.QRadioButton(Registration_2) 70 | self.galleryRadio.setGeometry(QtCore.QRect(430, 80, 261, 17)) 71 | font = QtGui.QFont() 72 | font.setPointSize(10) 73 | self.galleryRadio.setFont(font) 74 | self.galleryRadio.setObjectName("galleryRadio") 75 | self.shuffleButton = QtGui.QPushButton(Registration_2) 76 | self.shuffleButton.setGeometry(QtCore.QRect(630, 460, 151, 31)) 77 | font = QtGui.QFont() 78 | font.setPointSize(10) 79 | self.shuffleButton.setFont(font) 80 | self.shuffleButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) 81 | self.shuffleButton.setMouseTracking(False) 82 | self.shuffleButton.setObjectName("shuffleButton") 83 | self.numberOfImages = QtGui.QLabel(Registration_2) 84 | self.numberOfImages.setGeometry(QtCore.QRect(40, 30, 121, 21)) 85 | font = QtGui.QFont() 86 | font.setPointSize(10) 87 | self.numberOfImages.setFont(font) 88 | self.numberOfImages.setObjectName("numberOfImages") 89 | self.comboBox = QtGui.QComboBox(Registration_2) 90 | self.comboBox.setGeometry(QtCore.QRect(170, 30, 41, 21)) 91 | self.comboBox.setObjectName("comboBox") 92 | self.comboBox.addItem("") 93 | self.comboBox.addItem("") 94 | self.comboBox.addItem("") 95 | self.comboBox.addItem("") 96 | self.comboBox.addItem("") 97 | self.comboBox.addItem("") 98 | self.regImage = QtGui.QLabel(Registration_2) 99 | self.regImage.setGeometry(QtCore.QRect(20, 170, 600, 400)) 100 | self.regImage.setAutoFillBackground(False) 101 | self.regImage.setFrameShape(QtGui.QFrame.WinPanel) 102 | self.regImage.setFrameShadow(QtGui.QFrame.Sunken) 103 | self.regImage.setLineWidth(5) 104 | self.regImage.setText("") 105 | self.regImage.setPixmap(QtGui.QPixmap("new.png")) 106 | self.regImage.setScaledContents(True) 107 | self.regImage.setObjectName("regImage") 108 | self.selectImage = QtGui.QLabel(Registration_2) 109 | self.selectImage.setGeometry(QtCore.QRect(90, 110, 111, 21)) 110 | font = QtGui.QFont() 111 | font.setPointSize(10) 112 | self.selectImage.setFont(font) 113 | self.selectImage.setObjectName("selectImage") 114 | self.selectImage.setDisabled(True) 115 | self.selectButton = QtGui.QToolButton(Registration_2) 116 | self.selectButton.setGeometry(QtCore.QRect(190, 110, 25, 19)) 117 | self.selectButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) 118 | self.selectButton.setObjectName("selectButton") 119 | self.selectButton.setDisabled(True) 120 | self.groupBox = QtGui.QGroupBox(Registration_2) 121 | self.groupBox.setGeometry(QtCore.QRect(630, 180, 151, 51)) 122 | font = QtGui.QFont() 123 | font.setPointSize(10) 124 | self.groupBox.setFont(font) 125 | self.groupBox.setFlat(False) 126 | self.groupBox.setObjectName("groupBox") 127 | self.toleranceSlider = QtGui.QSlider(self.groupBox) 128 | self.toleranceSlider.setGeometry(QtCore.QRect(0, 20, 149, 22)) 129 | self.toleranceSlider.setMinimum(20) 130 | self.toleranceSlider.setMaximum(60) 131 | self.toleranceSlider.setSliderPosition(40) 132 | self.toleranceSlider.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) 133 | self.toleranceSlider.setOrientation(QtCore.Qt.Horizontal) 134 | self.toleranceSlider.setObjectName("toleranceSlider") 135 | self.browseImage = QtGui.QLabel(Registration_2) 136 | self.browseImage.setGeometry(QtCore.QRect(470, 110, 111, 21)) 137 | self.browseImage.setDisabled(True) 138 | font = QtGui.QFont() 139 | font.setPointSize(10) 140 | self.browseImage.setFont(font) 141 | self.browseImage.setObjectName("browseImage") 142 | self.browseButton = QtGui.QToolButton(Registration_2) 143 | self.browseButton.setGeometry(QtCore.QRect(580, 110, 25, 19)) 144 | self.browseButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) 145 | self.browseButton.setObjectName("browseButton") 146 | self.browseButton.setDisabled(True) 147 | 148 | #click button 1 149 | self.clickpoint1 = QtGui.QPushButton(Registration_2) 150 | self.clickpoint1.setGeometry(QtCore.QRect(self.posax,self.posay,self.tvalue,self.tvalue)) 151 | self.clickpoint1.setMinimumSize(QtCore.QSize(20, 20)) 152 | self.clickpoint1.setMaximumSize(QtCore.QSize(60, 60)) 153 | self.clickpoint1.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) 154 | self.clickpoint1.setMouseTracking(True) 155 | self.clickpoint1.setText("") 156 | self.clickpoint1.setObjectName("clickpoint1") 157 | 158 | #click button 2 159 | self.clickpoint2 = QtGui.QPushButton(Registration_2) 160 | self.clickpoint2.setGeometry(QtCore.QRect(320+self.bx,170+self.by,self.tvalue,self.tvalue)) 161 | self.clickpoint2.setMinimumSize(QtCore.QSize(20, 20)) 162 | self.clickpoint2.setMaximumSize(QtCore.QSize(60, 60)) 163 | self.clickpoint2.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) 164 | self.clickpoint2.setMouseTracking(True) 165 | self.clickpoint2.setText("") 166 | self.clickpoint2.setObjectName("clickpoint2") 167 | 168 | #click button 3 169 | self.clickpoint3 = QtGui.QPushButton(Registration_2) 170 | self.clickpoint3.setGeometry(QtCore.QRect(20+self.cx,445+self.cy,self.tvalue,self.tvalue)) 171 | self.clickpoint3.setMinimumSize(QtCore.QSize(20, 20)) 172 | self.clickpoint3.setMaximumSize(QtCore.QSize(60, 60)) 173 | self.clickpoint3.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) 174 | self.clickpoint3.setMouseTracking(True) 175 | self.clickpoint3.setText("") 176 | self.clickpoint3.setObjectName("clickpoint3") 177 | self.finishButton = QtGui.QPushButton(Registration_2) 178 | self.finishButton.setGeometry(QtCore.QRect(630, 530, 151, 31)) 179 | font = QtGui.QFont() 180 | font.setPointSize(10) 181 | self.finishButton.setFont(font) 182 | self.finishButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) 183 | self.finishButton.setObjectName("finishButton") 184 | 185 | 186 | self.databaseRadio.raise_() 187 | self.galleryRadio.raise_() 188 | self.shuffleButton.raise_() 189 | self.numberOfImages.raise_() 190 | self.comboBox.raise_() 191 | self.regImage.raise_() 192 | self.selectImage.raise_() 193 | self.selectButton.raise_() 194 | self.finishButton.raise_() 195 | self.groupBox.raise_() 196 | self.browseImage.raise_() 197 | self.browseButton.raise_() 198 | self.clickpoint1.raise_() 199 | self.clickpoint2.raise_() 200 | self.clickpoint3.raise_() 201 | self.finishButton.raise_() 202 | 203 | self.retranslateUi(Registration_2) 204 | self.databaseRadio.clicked['bool'].connect(self.selectImage.setEnabled) 205 | self.databaseRadio.clicked['bool'].connect(self.selectButton.setEnabled) 206 | self.galleryRadio.clicked['bool'].connect(self.browseImage.setEnabled) 207 | self.galleryRadio.clicked['bool'].connect(self.browseButton.setEnabled) 208 | self.databaseRadio.clicked['bool'].connect(self.browseImage.setDisabled) 209 | self.databaseRadio.clicked['bool'].connect(self.browseButton.setDisabled) 210 | self.galleryRadio.clicked['bool'].connect(self.selectImage.setDisabled) 211 | self.galleryRadio.clicked['bool'].connect(self.selectButton.setDisabled) 212 | #self.clickpoint1.released.connect(self.clickpointsshuffle) 213 | QtCore.QObject.connect(self.clickpoint1, QtCore.SIGNAL(_fromUtf8("clicked()")), self.shutdown) 214 | 215 | 216 | self.shuffleButton.clicked['bool'].connect(self.clickpointsshuffle) 217 | QtCore.QObject.connect(self.finishButton, QtCore.SIGNAL(_fromUtf8("clicked()")), Registration_2.close) 218 | self.toleranceSlider.valueChanged['int'].connect(self.settolerance) 219 | 220 | self.clickpoint1.clicked['bool'].connect(self.saveclickpoint1) 221 | self.clickpoint2.clicked['bool'].connect(self.saveclickpoint2) 222 | self.clickpoint3.clicked['bool'].connect(self.saveclickpoint3) 223 | 224 | QtCore.QMetaObject.connectSlotsByName(Registration_2) 225 | 226 | def saveclickpoint1(self,token): 227 | #save position of button 1 to database 228 | #try: 229 | # self.query= "INSERT into registration(img1) where Username='p'""VALUES (%s)" 230 | # self.a= '123' 231 | # self.new=self.a 232 | # self.args=(self.new) 233 | # self.db = mysql.connector.connect(host='localhost', database='python_mysql',user = 'root', password = '2864') 234 | # self.cursor=self.db.cursor() 235 | # self.cursor.execute(self.query,self.args) 236 | #self.cursor.execute("SELECT * from registration where Username = %s",'Sudarshan') 237 | #rows = self.cursor.fetchone() 238 | #print(rows) 239 | #self.db.commit() 240 | 241 | # except Error as e: 242 | # print(e) 243 | # 244 | # finally: 245 | # self.cursor.close() 246 | # self.db.close() 247 | self.nextimage() 248 | 249 | def saveclickpoint2(self,token): 250 | #save position of button 2 to database 251 | self.nextimage() 252 | def saveclickpoint3(self,token): 253 | #save position of button 3 to database 254 | self.nextimage() 255 | 256 | def nextimage(self): 257 | str=["1.png","2.png"] 258 | if self.imagenum <2: 259 | self.regImage.setPixmap(QtGui.QPixmap(str[self.imagenum])) 260 | self.imagenum = self.imagenum + 1 261 | else: 262 | self.clickpoint1.hide() 263 | self.clickpoint2.hide() 264 | self.clickpoint3.hide() 265 | self.clickpointsshuffle() 266 | 267 | def settolerance(self,a): 268 | self.tvalue = a 269 | self.clickpoint1.setGeometry(QtCore.QRect(self.posax,self.posay,self.tvalue,self.tvalue)) 270 | self.clickpoint2.setGeometry(QtCore.QRect(self.posbx,self.posby,self.tvalue,self.tvalue)) 271 | self.clickpoint3.setGeometry(QtCore.QRect(self.poscx,self.poscy,self.tvalue,self.tvalue)) 272 | 273 | def clickpointsshuffle(self): 274 | self.ax=randint(0,240) 275 | self.ay=randint(0,215) 276 | self.posax = 20+self.ax 277 | self.posay = 170+self.ay 278 | self.clickpoint1.setGeometry(QtCore.QRect(20+self.ax,170+self.ay,self.tvalue,self.tvalue)) 279 | self.bx=randint(0,240) 280 | self.by=randint(0,215) 281 | self.posbx = 320+self.bx 282 | self.posby = 170+self.by 283 | self.clickpoint2.setGeometry(QtCore.QRect(320+self.bx,170+self.by,self.tvalue,self.tvalue)) 284 | self.cx=randint(0,540) 285 | self.cy=randint(0,65) 286 | self.poscx = 20+self.cx 287 | self.poscy = 445+self.cy 288 | self.clickpoint3.setGeometry(QtCore.QRect(20+self.cx,445+self.cy,self.tvalue,self.tvalue)) 289 | #print(self.posax,self.posay) 290 | 291 | def shutdown(self): 292 | self.comboBox.setDisabled(True) 293 | #self.toleranceSlider.setDisabled(True) 294 | self.selectImage.setDisabled(True) 295 | self.databaseRadio.setDisabled(True) 296 | self.galleryRadio.setDisabled(True) 297 | self.browseButton.setDisabled(True) 298 | self.browseImage.setDisabled(True) 299 | self.selectButton.setDisabled(True) 300 | self.numberOfImages.setDisabled(True) 301 | self.groupBox.setDisabled(True) 302 | 303 | 304 | 305 | def retranslateUi(self, Registration_2): 306 | _translate = QtCore.QCoreApplication.translate 307 | Registration_2.setWindowTitle(_translate("Registration_2", "Registration (step 2 of 2)")) 308 | self.databaseRadio.setText(_translate("Registration_2", "Choose Images from system database")) 309 | self.galleryRadio.setText(_translate("Registration_2", "Browse Images from gallery")) 310 | self.shuffleButton.setText(_translate("Registration_2", "Shuffle Click-points")) 311 | self.numberOfImages.setText(_translate("Registration_2", "Number of Images : ")) 312 | self.comboBox.setItemText(0, _translate("Registration_2", "3")) 313 | self.comboBox.setItemText(1, _translate("Registration_2", "4")) 314 | self.comboBox.setItemText(2, _translate("Registration_2", "5")) 315 | self.comboBox.setItemText(3, _translate("Registration_2", "6")) 316 | self.comboBox.setItemText(4, _translate("Registration_2", "7")) 317 | self.comboBox.setItemText(5, _translate("Registration_2", "8")) 318 | self.selectImage.setText(_translate("Registration_2", "Select Images : ")) 319 | self.selectButton.setText(_translate("Registration_2", "...")) 320 | self.groupBox.setTitle(_translate("Registration_2", "Click-point Tolerance")) 321 | self.browseImage.setText(_translate("Registration_2", "Browse Images :")) 322 | self.browseButton.setText(_translate("Registration_2", "...")) 323 | self.finishButton.setText(_translate("Registration_2", "Finish")) 324 | 325 | -------------------------------------------------------------------------------- /home_ui.py: -------------------------------------------------------------------------------- 1 | 2 | from PyQt4 import QtCore, QtGui 3 | from PyQt4.QtCore import * 4 | from PyQt4.QtGui import * 5 | import os 6 | import sys 7 | import random 8 | from Crypto.Cipher import AES 9 | from Crypto.Hash import SHA256 10 | from Crypto import Random 11 | 12 | try: 13 | _fromUtf8 = QtCore.QString.fromUtf8 14 | except AttributeError: 15 | def _fromUtf8(s): 16 | return s 17 | 18 | try: 19 | _encoding = QtGui.QApplication.UnicodeUTF8 20 | def _translate(context, text, disambig): 21 | return QtGui.QApplication.translate(context, text, disambig, _encoding) 22 | except AttributeError: 23 | def _translate(context, text, disambig): 24 | return QtGui.QApplication.translate(context, text, disambig) 25 | 26 | class Ui_Home(QMainWindow): 27 | def __init__(self,cpx,cpy): 28 | self.cpx = cpx 29 | self.cpy = cpy 30 | self.passkey = self.genPasskey(self.cpx,self.cpy) 31 | QMainWindow.__init__(self) 32 | self.setupUi(self) 33 | 34 | def setupUi(self, Home): 35 | Home.setObjectName(_fromUtf8("Home")) 36 | Home.resize(300, 200) 37 | Home.setMinimumSize(QtCore.QSize(300, 200)) 38 | Home.setMaximumSize(QtCore.QSize(300, 200)) 39 | self.groupBoxE = QtGui.QGroupBox(Home) 40 | self.groupBoxE.setGeometry(QtCore.QRect(10, 10, 281, 71)) 41 | self.groupBoxE.setTitle(_fromUtf8("")) 42 | self.groupBoxE.setObjectName(_fromUtf8("groupBoxE")) 43 | self.labelLock = QtGui.QLabel(self.groupBoxE) 44 | self.labelLock.setGeometry(QtCore.QRect(10, 10, 101, 21)) 45 | font = QtGui.QFont() 46 | font.setPointSize(10) 47 | self.labelLock.setFont(font) 48 | self.labelLock.setObjectName(_fromUtf8("labelLock")) 49 | self.lineEditLock = QtGui.QLineEdit(self.groupBoxE) 50 | self.lineEditLock.setGeometry(QtCore.QRect(110, 10, 161, 20)) 51 | self.lineEditLock.setReadOnly(False) 52 | self.lineEditLock.setObjectName(_fromUtf8("lineEditLock")) 53 | self.lockButton = QtGui.QPushButton(self.groupBoxE) 54 | self.lockButton.setGeometry(QtCore.QRect(240, 40, 31, 23)) 55 | self.lockButton.setObjectName(_fromUtf8("lockButton")) 56 | self.groupBoxD = QtGui.QGroupBox(Home) 57 | self.groupBoxD.setGeometry(QtCore.QRect(10, 90, 281, 71)) 58 | self.groupBoxD.setTitle(_fromUtf8("")) 59 | self.groupBoxD.setObjectName(_fromUtf8("groupBoxD")) 60 | self.labelUnlock = QtGui.QLabel(self.groupBoxD) 61 | self.labelUnlock.setGeometry(QtCore.QRect(10, 10, 101, 21)) 62 | font = QtGui.QFont() 63 | font.setPointSize(10) 64 | self.labelUnlock.setFont(font) 65 | self.labelUnlock.setObjectName(_fromUtf8("labelUnlock")) 66 | self.lineEditUnlock = QtGui.QLineEdit(self.groupBoxD) 67 | self.lineEditUnlock.setGeometry(QtCore.QRect(110, 10, 161, 20)) 68 | self.lineEditUnlock.setObjectName(_fromUtf8("lineEditUnlock")) 69 | self.unlockButton = QtGui.QPushButton(self.groupBoxD) 70 | self.unlockButton.setGeometry(QtCore.QRect(240, 40, 31, 23)) 71 | self.unlockButton.setObjectName(_fromUtf8("unlockButton")) 72 | self.logoutButton = QtGui.QPushButton(Home) 73 | self.logoutButton.setGeometry(QtCore.QRect(110, 170, 75, 23)) 74 | self.logoutButton.setObjectName(_fromUtf8("logoutButton")) 75 | 76 | self.retranslateUi(Home) 77 | QtCore.QMetaObject.connectSlotsByName(Home) 78 | Home.setTabOrder(self.logoutButton, self.lineEditLock) 79 | Home.setTabOrder(self.lineEditLock, self.lockButton) 80 | Home.setTabOrder(self.lockButton, self.lineEditUnlock) 81 | Home.setTabOrder(self.lineEditUnlock, self.unlockButton) 82 | self.lockButton.clicked['bool'].connect(self.getFileforEnc) 83 | self.unlockButton.clicked['bool'].connect(self.getFileforDec) 84 | self.logoutButton.clicked['bool'].connect(self.close) 85 | 86 | 87 | def retranslateUi(self, Home): 88 | Home.setWindowTitle(_translate("Home", "Home", None)) 89 | self.labelLock.setText(_translate("Home", "File to lock :", None)) 90 | self.lineEditLock.setPlaceholderText(_translate("Home", "Enter filename with extension", None)) 91 | self.lockButton.setText(_translate("Home", "OK", None)) 92 | self.labelUnlock.setText(_translate("Home", "File to unlock :", None)) 93 | self.lineEditUnlock.setPlaceholderText(_translate("Home", "Enter filename with extension", None)) 94 | self.unlockButton.setText(_translate("Home", "OK", None)) 95 | self.logoutButton.setText(_translate("Home", "Log Out", None)) 96 | 97 | 98 | #a passkey is generated using the user's clickpoints 99 | '''example: if number of images is 3 100 | clickpoints on x-cordinates , cpx = [168,193, 69] 101 | and clickpoints on y-cordinates , cpy = [185,120,151] 102 | then, passkey="16819369185120151" ''' 103 | def genPasskey(self,cpx,cpy): 104 | passkey="" 105 | cplist = cpx+cpy #cplist : list of clickpoints 106 | for i in cplist: 107 | passkey += str(i) 108 | return passkey 109 | 110 | 111 | #gets the filename and calls the encrypt function 112 | def getFileforEnc(self): 113 | try: 114 | self.filename = str(self.lineEditLock.text()) 115 | self.encrypt(self.getKey(str(self.passkey)), self.filename) 116 | QMessageBox.information(self, 'Done','File Encrypted') 117 | except IOError as e: 118 | errorstr = str(e) 119 | QtGui.QMessageBox.warning(self, 'Sorry!', errorstr) 120 | finally: 121 | pass 122 | 123 | #gets the filename and calls the decrypt function 124 | def getFileforDec(self): 125 | try: 126 | self.filename = str(self.lineEditUnlock.text()) 127 | self.decrypt(self.getKey(str(self.passkey)), self.filename) 128 | QMessageBox.information(self, 'Done','File Decrypted') 129 | except IOError as e: 130 | errorstr = str(e) 131 | QtGui.QMessageBox.warning(self, 'Sorry!', errorstr) 132 | finally: 133 | pass 134 | 135 | 136 | #encrypts the file if it exists 137 | def encrypt(self, key, filename): 138 | chunksize = 64*1024 139 | outputFile = "(encrypted)"+filename 140 | filesize = str(os.path.getsize(filename)).zfill(16) 141 | IV = Random.new().read(16) #initialization vector 142 | 143 | encryptor = AES.new(key, AES.MODE_CBC, IV) #AES.MODE_CBC is the chain block cipher mode of AES encryption 144 | 145 | with open(filename, 'rb') as infile: 146 | with open(outputFile, 'wb') as outfile: 147 | outfile.write(filesize.encode('utf-8')) 148 | outfile.write(IV) 149 | 150 | while True: 151 | chunk = infile.read(chunksize) 152 | 153 | if len(chunk) == 0: 154 | break 155 | elif len(chunk) % 16 != 0: 156 | chunk += b' ' * (16 - (len(chunk) % 16)) 157 | 158 | outfile.write(encryptor.encrypt(chunk)) 159 | 160 | 161 | #decrypts the file if it exists 162 | def decrypt(self, key, filename): 163 | chunksize = 64*1024 164 | outputFile = filename[11:] #[11:] is to strip the "(encrypted)" characters at the front of the filename 165 | 166 | with open(filename, 'rb') as infile: 167 | filesize = int(infile.read(16)) 168 | IV = infile.read(16) 169 | 170 | decryptor = AES.new(key, AES.MODE_CBC, IV) 171 | 172 | with open(outputFile, 'wb') as outfile: 173 | while True: 174 | chunk = infile.read(chunksize) 175 | 176 | if len(chunk) == 0: 177 | break 178 | 179 | outfile.write(decryptor.decrypt(chunk)) 180 | outfile.truncate(filesize) 181 | 182 | 183 | #generates a haskey from the passkey 184 | #SHA-256 is used for cryptographic hash algorithm (SHA : Secure Hash Algorithm) 185 | def getKey(self, passkey): 186 | hasher = SHA256.new(passkey.encode('utf-8')) 187 | return hasher.digest() 188 | 189 | 190 | #prompts the user when the logout button or the close button is pressed 191 | def closeEvent(self, event): 192 | quit_msg = "Are you sure you want to logout and exit?" 193 | reply = QtGui.QMessageBox.question(self, 'Message', 194 | quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) 195 | 196 | if reply == QtGui.QMessageBox.Yes: 197 | event.accept() 198 | else : 199 | event.ignore() 200 | 201 | 202 | # if __name__ == '__main__': 203 | # app = QtGui.QApplication(sys.argv) 204 | # mainWindow = Ui_Home([1,2,3],[4,5,6]) 205 | # mainWindow.show() 206 | # sys.exit(app.exec()) -------------------------------------------------------------------------------- /home_ui.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/home_ui.pyc -------------------------------------------------------------------------------- /image_retrieve.py: -------------------------------------------------------------------------------- 1 | import mysql.connector 2 | from mysql.connector import Error, MySQLConnection 3 | from PyQt4 import QtCore, QtGui 4 | from PyQt4.QtGui import QApplication, QDialog, QWidget, QMainWindow 5 | import os 6 | 7 | class imageRetrieve(): 8 | def write_file(self,data, filename): 9 | with open(filename, 'wb') as f: 10 | f.write(data) 11 | 12 | def read_blob(self,author_id, filename): 13 | # select photo column of a specific author 14 | query = "SELECT img_addr FROM image_data WHERE img_id = %s" 15 | 16 | 17 | try: 18 | # query blob data form the authors table 19 | conn= mysql.connector.connect(host='localhost',database='python_mysql',user='root',password='2864') 20 | cursor = conn.cursor() 21 | cursor.execute(query, (author_id,)) 22 | photo = cursor.fetchone()[0] 23 | 24 | # write blob data into a file 25 | self.write_file(photo, filename) 26 | 27 | except Error as e: 28 | errorstr = str(e) 29 | QtGui.QMessageBox.warning(self, 'Sorry!', errorstr) 30 | 31 | finally: 32 | cursor.close() 33 | conn.close() 34 | 35 | def main(self): 36 | self.read_blob(1, "1.png") 37 | self.read_blob(2, "2.png") 38 | self.read_blob(3, "3.png") 39 | self.read_blob(4, "4.png") 40 | self.read_blob(5, "5.png") 41 | self.read_blob(6, "6.png") 42 | self.read_blob(7, "7.png") 43 | self.read_blob(8, "8.png") 44 | self.read_blob(9, "9.png") 45 | self.read_blob(10, "10.png") 46 | self.read_blob(11, "11.png") 47 | self.read_blob(12, "12.png") 48 | 49 | def remove_images(self): 50 | os.remove("1.png") 51 | os.remove("2.png") 52 | os.remove("3.png") 53 | os.remove("4.png") 54 | os.remove("5.png") 55 | os.remove("6.png") 56 | os.remove("7.png") 57 | os.remove("8.png") 58 | os.remove("9.png") 59 | os.remove("10.png") 60 | os.remove("11.png") 61 | os.remove("12.png") 62 | 63 | if __name__ == '__main__': 64 | imageRetrieve = imageRetrieve() 65 | imageRetrieve.main() 66 | 67 | -------------------------------------------------------------------------------- /image_retrieve.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/image_retrieve.pyc -------------------------------------------------------------------------------- /image_store.py: -------------------------------------------------------------------------------- 1 | def read_file(filename): 2 | with open(filename, 'rb') as f: 3 | photo = f.read() 4 | return photo 5 | from mysql.connector import MySQLConnection, Error 6 | import mysql.connector 7 | 8 | def update_blob(author_id, filename): 9 | # read file 10 | data = read_file(filename) 11 | 12 | # prepare update query and data 13 | query = "update image_data SET img_addr = %s WHERE img_id = %s" 14 | 15 | args = (data, author_id) 16 | 17 | 18 | try: 19 | conn= mysql.connector.connect(host='localhost',database='python_mysql',user='root',password='2864') 20 | cursor = conn.cursor() 21 | cursor.execute(query, args) 22 | conn.commit() 23 | cursor.close() 24 | conn.close() 25 | except Error as e: 26 | print(e) 27 | finally: 28 | print('test') 29 | # cursor.close() 30 | # conn.close() 31 | 32 | 33 | def main(): 34 | update_blob(1, "1.png") 35 | update_blob(2, "2.png") 36 | update_blob(3, "3.png") 37 | update_blob(4, "4.png") 38 | update_blob(5, "5.png") 39 | update_blob(6, "6.png") 40 | update_blob(7, "7.png") 41 | update_blob(8, "8.png") 42 | update_blob(9, "9.png") 43 | update_blob(10, "10.png") 44 | update_blob(11, "11.png") 45 | update_blob(12, "12.png") 46 | 47 | 48 | 49 | if __name__ == '__main__': 50 | main() 51 | 52 | 53 | -------------------------------------------------------------------------------- /imageselect.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtCore, QtGui 2 | from PyQt4.QtGui import * 3 | import mysql.connector 4 | from mysql.connector import * 5 | from mysql.connector import MySQLConnection,Error 6 | from registration_2_ui import * 7 | from image_retrieve import * 8 | import sys 9 | import os 10 | 11 | try: 12 | _fromUtf8 = QtCore.QString.fromUtf8 13 | except AttributeError: 14 | def _fromUtf8(s): 15 | return s 16 | 17 | try: 18 | _encoding = QtGui.QApplication.UnicodeUTF8 19 | def _translate(context, text, disambig): 20 | return QtGui.QApplication.translate(context, text, disambig, _encoding) 21 | except AttributeError: 22 | def _translate(context, text, disambig): 23 | return QtGui.QApplication.translate(context, text, disambig) 24 | 25 | 26 | class Ui_imageselect(QMainWindow): 27 | def __init__(self,num ): 28 | QMainWindow.__init__(self) 29 | self.setupUi(self) 30 | self.currentbutton = 0 31 | self.num = num #### #get number of images ie 'num' from registration 2 32 | self.status = [] #### #list of click status of 12 buttons 33 | self.clicks = 0 34 | self.imageRetrieve = imageRetrieve() 35 | 36 | for i in range(12): 37 | self.status.append(False) 38 | 39 | 40 | 41 | def setupUi(self, imageselect): 42 | imageselect.setObjectName(_fromUtf8("imageselect")) 43 | imageselect.resize(617, 594) 44 | imageselect.setWindowModality(QtCore.Qt.ApplicationModal) 45 | 46 | 47 | #********************************extracting 12 images from Database and saving them in a list************************** 48 | 49 | #*****************************************fetching address from db********************************************************************* 50 | # self.imageList = [] 51 | # try: 52 | # self.db=mysql.connector.connect(host="localhost", database="python_mysql",user="root",password="2864") 53 | # self.cursor=self.db.cursor() 54 | # for i in range(12): 55 | # self.cursor.execute("select * from image_data where img_id=%s",(i+1,)) 56 | # rows=self.cursor.fetchone() 57 | # #print(rows[1]) 58 | # self.imageList.append(rows[1]) 59 | # #print(self.imageList[i]) 60 | # imageList = self.imageList 61 | # except Error as e: 62 | # print(e) 63 | # 64 | # finally: 65 | # self.cursor.close() 66 | # self.db.close() 67 | 68 | #*****************************************retrieving images from db and using the address***************************** 69 | #create images here. 70 | self.imageList = [] 71 | for i in range(12): 72 | self.imageList.append(str(i+1)+".png") 73 | 74 | #****************************************************creating 12 icons for 12 push buttons**************************** 75 | iconList = [] 76 | for i in range(12): 77 | iconList.append(QtGui.QIcon()) 78 | iconList[i].addPixmap(QtGui.QPixmap(_fromUtf8(self.imageList[i])), QtGui.QIcon.Normal, QtGui.QIcon.Off) 79 | 80 | #****************************************************creating 12 push buttons***************************************** 81 | self.imageButton = [] 82 | shiftx=0 #difference between the positions on x-direction for buttons on 1st row 83 | shifty=0 #difference between the positions on x-direction for buttons on 2nd row 84 | shiftz=0 #difference between the positions on x-direction for buttons on 3rd row 85 | shiftu=0 #difference between the positions on x-direction for buttons on 4th row 86 | 87 | for i in range(12): 88 | self.img = QtGui.QPushButton(imageselect) 89 | if ((i==0) or (i==1) or (i==2)): #setting geometry for 3 pushbuttons img[0],img[1] and img[2] 90 | self.img.setGeometry(QtCore.QRect(10+shiftx, 20, 170, 120)) 91 | shiftx=shiftx+185 92 | if ((i==3) or (i==4) or (i==5)): #setting geometry for 3 pushbuttons img[3],img[4] and img[5] 93 | self.img.setGeometry(QtCore.QRect(10+shifty, 150, 170, 120)) 94 | shifty=shifty+185 95 | if ((i==6) or (i==7) or (i==8)): #setting geometry for 3 pushbuttons img[6],img[7] and img[8] 96 | self.img.setGeometry(QtCore.QRect(10+shiftz, 280, 170, 120)) 97 | shiftz=shiftz+185 98 | if ((i==9) or (i==10) or (i==11)): #setting geometry for 3 pushbuttons img[9],img[10] and img[11] 99 | self.img.setGeometry(QtCore.QRect(10+shiftu, 410, 170, 120)) 100 | shiftu=shiftu+185 101 | self.img.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) 102 | self.img.setText(_fromUtf8("")) 103 | self.img.setIcon(iconList[i]) 104 | self.img.setIconSize(QtCore.QSize(180, 100)) 105 | self.img.setCheckable(True) 106 | self.img.setFlat(True) 107 | self.img.setObjectName(_fromUtf8("img1")) 108 | self.imageButton.append(self.img) 109 | #----------------------------------------------------------------------------------------------------------------------# 110 | 111 | 112 | self.open = QtGui.QPushButton(imageselect) 113 | self.open.setGeometry(QtCore.QRect(390, 540, 101, 31)) 114 | self.open.setDisabled(True) 115 | font = QtGui.QFont() 116 | font.setPointSize(10) 117 | font.setBold(True) 118 | font.setWeight(75) 119 | self.open.setFont(font) 120 | self.open.setObjectName(_fromUtf8("open")) 121 | self.verticalScrollBar = QtGui.QScrollBar(imageselect) 122 | self.verticalScrollBar.setGeometry(QtCore.QRect(600, 0, 20, 591)) 123 | self.verticalScrollBar.setOrientation(QtCore.Qt.Vertical) 124 | self.verticalScrollBar.setObjectName(_fromUtf8("verticalScrollBar")) 125 | self.retranslateUi(imageselect) 126 | 127 | self.open.clicked['bool'].connect(self.closeImageSelect) 128 | 129 | #**************try button clicked option using loop or something similar******************** 130 | # for j in range(12): 131 | # print(j) 132 | # self.currentbutton = j 133 | # self.imageButton[j].clicked['bool'].connect(self.updateState) 134 | 135 | self.imageButton[0].clicked['bool'].connect(self.updateStatus0) 136 | self.imageButton[1].clicked['bool'].connect(self.updateStatus1) 137 | self.imageButton[2].clicked['bool'].connect(self.updateStatus2) 138 | self.imageButton[3].clicked['bool'].connect(self.updateStatus3) 139 | self.imageButton[4].clicked['bool'].connect(self.updateStatus4) 140 | self.imageButton[5].clicked['bool'].connect(self.updateStatus5) 141 | self.imageButton[6].clicked['bool'].connect(self.updateStatus6) 142 | self.imageButton[7].clicked['bool'].connect(self.updateStatus7) 143 | self.imageButton[8].clicked['bool'].connect(self.updateStatus8) 144 | self.imageButton[9].clicked['bool'].connect(self.updateStatus9) 145 | self.imageButton[10].clicked['bool'].connect(self.updateStatus10) 146 | self.imageButton[11].clicked['bool'].connect(self.updateStatus11) 147 | 148 | 149 | QtCore.QMetaObject.connectSlotsByName(imageselect) 150 | 151 | #******************updateStatus changes the status of the button,true if clicked and false if double clicked************ 152 | def updateStatus0(self,stat): 153 | self.status[0] = stat 154 | self.check(stat) 155 | 156 | def updateStatus1(self,stat): 157 | self.status[1] = stat 158 | self.check(stat) 159 | 160 | def updateStatus2(self,stat): 161 | self.status[2] = stat 162 | self.check(stat) 163 | 164 | def updateStatus3(self,stat): 165 | self.status[3] = stat 166 | self.check(stat) 167 | 168 | def updateStatus4(self,stat): 169 | self.status[4] = stat 170 | self.check(stat) 171 | 172 | def updateStatus5(self,stat): 173 | self.status[5] = stat 174 | self.check(stat) 175 | 176 | def updateStatus6(self,stat): 177 | self.status[6] = stat 178 | self.check(stat) 179 | 180 | def updateStatus7(self,stat): 181 | self.status[7] = stat 182 | self.check(stat) 183 | 184 | def updateStatus8(self,stat): 185 | self.status[8] = stat 186 | self.check(stat) 187 | 188 | def updateStatus9(self,stat): 189 | self.status[9] = stat 190 | self.check(stat) 191 | 192 | def updateStatus10(self,stat): 193 | self.status[10] = stat 194 | self.check(stat) 195 | 196 | def updateStatus11(self,stat): 197 | self.status[11] = stat 198 | self.check(stat) 199 | 200 | #*********check func increases 'clicks' if button is single clicked, decreases 'clicks' if button is double ckicked***** 201 | def check(self,stat): 202 | if stat==True: 203 | self.clicks = self.clicks+1 204 | else: 205 | self.clicks = self.clicks-1 206 | if self.clicks == self.num: 207 | self.disableUnckecked(True) 208 | else: 209 | self.disableUnckecked(False) 210 | 211 | #*************************************if image limit is reached, disable unckecked images******************************* 212 | def disableUnckecked(self,bl): 213 | for k in range(12): 214 | if self.status[k]==False: 215 | self.imageButton[k].setDisabled(bl) 216 | self.open.setEnabled(bl) 217 | 218 | def retranslateUi(self, imageselect): 219 | imageselect.setWindowTitle(_translate("imageselect", "Form", None)) 220 | self.open.setText(_translate("imageselect", "Open", None)) 221 | 222 | def closeImageSelect(self): 223 | self.close() 224 | 225 | 226 | 227 | -------------------------------------------------------------------------------- /imageselect.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/imageselect.pyc -------------------------------------------------------------------------------- /login.py: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtCore, QtGui 2 | import smtplib 3 | import string 4 | import socket 5 | import random 6 | from PyQt4.QtGui import * 7 | from PyQt4.QtCore import * 8 | import sys 9 | from recovery_ui import * 10 | from home_ui import * 11 | import mysql.connector 12 | import imageselect 13 | from mysql.connector import * 14 | from mysql.connector import Error,MySQLConnection 15 | from image_retrieve import * 16 | import json 17 | try: 18 | _fromUtf8 = QtCore.QString.fromUtf8 19 | except AttributeError: 20 | def _fromUtf8(s): 21 | return s 22 | 23 | try: 24 | _encoding = QtGui.QApplication.UnicodeUTF8 25 | def _translate(context, text, disambig): 26 | return QtGui.QApplication.translate(context, text, disambig, _encoding) 27 | except AttributeError: 28 | def _translate(context, text, disambig): 29 | return QtGui.QApplication.translate(context, text, disambig) 30 | 31 | 32 | 33 | class Ui_Login(QMainWindow): 34 | def __init__(self): 35 | QMainWindow.__init__(self) 36 | self.setupUi(self) 37 | self.imgRetrieve = imageRetrieve() 38 | self.temp=0 39 | self.imagenum=0 #counter for the images shown 40 | self.imgRetrieve.main() # main() function of the imageRetrieve class retrieves all the images from the database 41 | 42 | def setupUi(self, Login): 43 | Login.setObjectName(_fromUtf8("Login")) 44 | Login.resize(600, 400) 45 | Login.setFixedSize(600,400) 46 | Login.setWindowModality(QtCore.Qt.ApplicationModal) 47 | self.loginimage = ExtendedQLabel(Login) 48 | self.loginimage.setGeometry(QtCore.QRect(0, 0, 600, 400)) 49 | self.loginimage.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) 50 | self.loginimage.setObjectName(_fromUtf8("loginimage")) 51 | self.loginimage.setScaledContents(True) 52 | 53 | self.errorlabel = QtGui.QLabel(Login) 54 | self.errorlabel.setGeometry(QtCore.QRect(190, 215, 200, 50)) 55 | palette = QtGui.QPalette() 56 | brush = QtGui.QBrush(QtGui.QColor(255, 0, 0)) 57 | brush.setStyle(QtCore.Qt.SolidPattern) 58 | palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush) 59 | brush = QtGui.QBrush(QtGui.QColor(255, 0, 0)) 60 | brush.setStyle(QtCore.Qt.SolidPattern) 61 | palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush) 62 | brush = QtGui.QBrush(QtGui.QColor(120, 120, 120)) 63 | brush.setStyle(QtCore.Qt.SolidPattern) 64 | palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush) 65 | self.errorlabel.setPalette(palette) 66 | font = QtGui.QFont() 67 | font1 = QtGui.QFont() 68 | font.setPointSize(10) 69 | font1.setPointSize(10) 70 | font.setItalic(True) 71 | self.errorlabel.setFont(font) 72 | self.errorlabel.setText("") 73 | 74 | self.forgotButton=QtGui.QPushButton(Login) 75 | self.forgotButton.setGeometry(QtCore.QRect(300, 200, 100, 30)) 76 | self.forgotButton.setText("Forgot Password") 77 | 78 | self.clickpoint = QtGui.QPushButton(Login) 79 | self.clickpoint.setGeometry(QtCore.QRect(330, 90, 75, 51)) 80 | self.clickpoint.setObjectName(_fromUtf8("clickpoint")) 81 | self.okay = QtGui.QPushButton(Login) 82 | self.okay.setGeometry(QtCore.QRect(190, 200, 100, 30)) 83 | self.okay.setObjectName(_fromUtf8("Okay")) 84 | self.okay.setText("Login") 85 | self.lineEdit = QtGui.QLineEdit(Login) 86 | self.lineEdit.setGeometry(QtCore.QRect(190, 160, 210, 30)) 87 | self.lineEdit.setObjectName(_fromUtf8("lineEdit")) 88 | self.lineEdit.setFont(font1) 89 | self.retranslateUi(Login) 90 | self.okay.clicked['bool'].connect(self.GetUsername) 91 | self.clickpoint.setStyleSheet(_fromUtf8("\n" 92 | "background-color: rgb(0, 0, 0,0);\n")) 93 | self.clickpoint.setDisabled(True) 94 | self.clickpoint.clicked['bool'].connect(self.gencorrectImage) 95 | self.forgotButton.clicked['bool'].connect(self.emailfunc) 96 | self.clickpoint.setFlat(True) 97 | self.connect(self.loginimage,SIGNAL("clicked()"),self.genrandomImage) 98 | QtCore.QMetaObject.connectSlotsByName(Login) 99 | 100 | 101 | def retranslateUi(self, Login): 102 | Login.setWindowTitle(_translate("Login", "Login", None)) 103 | self.lineEdit.setPlaceholderText(_translate("Login", "username", None)) 104 | 105 | 106 | #sending mail for recovery 107 | def emailfunc(self): 108 | self.uname=str(self.lineEdit.text()) 109 | if not self.uname: 110 | self.errorlabel.setText("***Enter correct username***") 111 | 112 | else: 113 | try: 114 | self.code='' 115 | for i in range(8): 116 | send=choice(string.ascii_letters) 117 | self.code=self.code+send 118 | self.db=mysql.connector.connect(host="localhost", database="python_mysql",user="root",password="2864") 119 | self.cursor=self.db.cursor() 120 | self.temp=(self.code,self.uname) 121 | self.cursor.execute("UPDATE registration set recovery_txt=%s where Username=%s",self.temp) 122 | self.db.commit() 123 | self.cursor.execute("select * from registration where username=%s",(self.uname,)) 124 | self.rows=self.cursor.fetchone() 125 | self.send_mail(self.rows[4]) 126 | QMessageBox.information(self, 'Check your Email!','An email has been sent to your account with the recovery text.') 127 | self.close() 128 | self.recover = Ui_Recovery(self.uname,self.code) #recovery code and username are passed as arguments 129 | self.recover.show() 130 | except Error as e: 131 | errorstr = str(e) 132 | QtGui.QMessageBox.warning(self, 'Sorry!', errorstr) 133 | except TypeError: 134 | self.errorlabel.setText("***Username not found***") 135 | except smtplib.SMTPAuthenticationError as e: 136 | strerr = str(e) 137 | QtGui.QMessageBox.warning(self, 'Sorry!', strerr +"\n\n\nSystem could not login. Try again later!") 138 | except TimeoutError as e: 139 | strerr = str(e) 140 | QtGui.QMessageBox.warning(self, 'Sorry!', strerr +"\n\n\nSystem could not login. Try again later!") 141 | #except: 142 | # QtGui.QMessageBox.warning(self, 'Sorry!', "Something went wrong. Try again later!") 143 | 144 | finally: 145 | self.cursor.close() 146 | self.db.close() 147 | 148 | 149 | #send_mail function sends the recovery text from iamnotsparsha@gmail.com to the user Email 150 | def send_mail(self,userEmail): 151 | #gmail connection 152 | try: 153 | mail=smtplib.SMTP('smtp.gmail.com:587') 154 | mail.ehlo() 155 | mail.starttls() 156 | mail.login('iamnotsparsha@gmail.com', 'fantasy.101') 157 | content = "Please use this code to log into your account: " 158 | content = 'Subject: %s\n\n%s' % ("Password Reset", content) 159 | content=content+ self.code 160 | mail.sendmail('iamnotsparsha@gmail.com',userEmail,content) 161 | mail.close() 162 | 163 | except UnboundLocalError as e: 164 | strerr = str(e) 165 | QtGui.QMessageBox.warning(self, 'Sorry!', strerr) 166 | 167 | finally: 168 | pass 169 | 170 | 171 | def GetUsername(self): 172 | #******************first the username is fetched from the Database************************* 173 | self.uname=str(self.lineEdit.text()) 174 | if not self.uname: 175 | self.errorlabel.setText("***Enter a username***") 176 | else: 177 | try: 178 | self.db=mysql.connector.connect(host="localhost", database="python_mysql",user="root",password="2864") 179 | self.cursor=self.db.cursor() 180 | self.cursor.execute("select * from registration where username=%s",(self.uname,)) 181 | rows=self.cursor.fetchone() 182 | if not rows: 183 | self.errorlabel.setText("***Invalid Username***") 184 | else: 185 | '''*************if the username is matched, user details like number of images(inum), 186 | tolerance value(tvalue),list of images(imageList) and clickpoints(cpx,cpy) 187 | are fetched from the database************************''' 188 | self.inum=rows[5] 189 | self.tvalue=rows[6] 190 | self.imageList=[] #list of user images 191 | self.cpx=[] #list of x-coordinates for clickpoints 192 | self.cpy=[] #list of Y-coordinates for clickpoints 193 | 194 | for i in range (self.inum): 195 | self.new=json.loads(rows[i+7]) 196 | self.imageList.append(self.new[0]) 197 | self.cpx.append(self.new[1]) 198 | self.cpy.append(self.new[2]) 199 | self.clickpoint.setDisabled(False) 200 | '''************after username is matched, clickpoint is enabled, 201 | correct image is shown and remaining entities are closed***********''' 202 | self.gencorrectImage() 203 | self.lineEdit.close() 204 | self.okay.close() 205 | self.forgotButton.close() 206 | self.errorlabel.close() 207 | 208 | except Error as e: 209 | strerr = str(e) 210 | QtGui.QMessageBox.warning(self, 'Try again later!', strerr) 211 | finally: 212 | self.cursor.close() 213 | self.db.close() 214 | 215 | #if the user clicks on correct series of clickpoints, correct series of images are generated 216 | def gencorrectImage(self): 217 | if self.imagenum ", None)) 124 | 125 | 126 | @QtCore.pyqtSignature("on_pushNext_clicked()") 127 | def open_reg_window2(self): 128 | self.err = "" 129 | self.fname = str(self.firstName.text()) 130 | self.lname = str(self.lastName.text()) 131 | self.uname = str(self.userName.text()) 132 | self.emailid = str(self.email.text()) 133 | 134 | try: 135 | self.db = mysql.connector.connect(host="localhost", database = "python_mysql", user = "root", password = "2864") 136 | self.cursor = self.db.cursor() 137 | self.query = "INSERT into registration(Fname, Lname, Username, Email)""VALUES (%s,%s,%s,%s)" 138 | self.value = (self.fname, self.lname, self.uname, self.emailid) 139 | self.cursor.execute(self.query,self.value) 140 | self.db.commit() 141 | 142 | except Error as e: 143 | self.err = e 144 | 145 | finally: 146 | self.cursor.close() 147 | self.db.close() 148 | 149 | 150 | if not self.fname: 151 | QtGui.QMessageBox.warning(self, 'Dang it!', 'First Name Missing') 152 | elif not self.lname: 153 | QtGui.QMessageBox.warning(self, 'Dang it!', 'Last Name Missing') 154 | elif not self.uname: 155 | QtGui.QMessageBox.warning(self, 'Dang it!', 'Username Missing') 156 | elif not self.emailid: 157 | QtGui.QMessageBox.warning(self, 'Dang it!', 'Email ID Missing') 158 | elif self.err!="": 159 | QtGui.QMessageBox.information(self, 'Sorry!', 'Username not available!') 160 | else: 161 | QtGui.QMessageBox.information(self, 'Awesome!!', 'User Added SUCCESSFULLY!') 162 | self.close() 163 | self.registration_2 = Ui_Registration_2(self.uname) #"uname" is used to access database in registration 2 164 | self.registration_2.show() -------------------------------------------------------------------------------- /registration_ui.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/registration_ui.pyc -------------------------------------------------------------------------------- /requirements/requirements.txt: -------------------------------------------------------------------------------- 1 | requirements 2 | - python 3.4 3 | - pycrypto 2.6.1 4 | - PyQt4 -(4.11.4)-gpl-Py3.4-Qt4.8.7-x32 5 | - MySQL 6 | -------------------------------------------------------------------------------- /screenshots/home.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/screenshots/home.JPG -------------------------------------------------------------------------------- /screenshots/image selection.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/screenshots/image selection.JPG -------------------------------------------------------------------------------- /screenshots/login.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/screenshots/login.JPG -------------------------------------------------------------------------------- /screenshots/main window.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/screenshots/main window.JPG -------------------------------------------------------------------------------- /screenshots/registration (step 1 of 2).JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/screenshots/registration (step 1 of 2).JPG -------------------------------------------------------------------------------- /screenshots/registration (step 2 of 2).JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdevkota007/Graphical-Password-Authentication-Using-Persuasive-Cued-Clickpoints-With-File-Encryption/b4acb4a049a876697e917d98267063edaa426559/screenshots/registration (step 2 of 2).JPG -------------------------------------------------------------------------------- /send_mail.py: -------------------------------------------------------------------------------- 1 | import smtplib 2 | import random 3 | import string 4 | 5 | #random string generation 6 | def send_mail(): 7 | code='' 8 | for i in range(8): 9 | send=random.choice(string.ascii_letters) 10 | code=code+send 11 | print(code) 12 | 13 | 14 | #gmail connection 15 | mail=smtplib.SMTP('smtp.gmail.com:587') 16 | mail.ehlo() 17 | mail.starttls() 18 | mail.login('iamnotsparsha@gmail.com', 'fantasy.101') 19 | content = "Please use this code to log into your account: " 20 | content = 'Subject: %s\n\n%s' % ("Password Reset", content) 21 | content=content+ code 22 | print(content) 23 | mail.sendmail('iamnotsparsha@gmail.com','iamnotsparsha@gmail.com',content) 24 | mail.close() 25 | -------------------------------------------------------------------------------- /test/imageselect scroll test.txt: -------------------------------------------------------------------------------- 1 | from PyQt4 import QtCore, QtGui 2 | from PyQt4.QtGui import * 3 | import mysql.connector 4 | from mysql.connector import * 5 | from mysql.connector import MySQLConnection,Error 6 | import sys 7 | 8 | try: 9 | _fromUtf8 = QtCore.QString.fromUtf8 10 | except AttributeError: 11 | def _fromUtf8(s): 12 | return s 13 | 14 | try: 15 | _encoding = QtGui.QApplication.UnicodeUTF8 16 | def _translate(context, text, disambig): 17 | return QtGui.QApplication.translate(context, text, disambig, _encoding) 18 | except AttributeError: 19 | def _translate(context, text, disambig): 20 | return QtGui.QApplication.translate(context, text, disambig) 21 | 22 | class Ui_imageselect(QMainWindow): 23 | clicks = 0 24 | 25 | def __init__(self): 26 | QMainWindow.__init__(self) 27 | self.setupUi(self) 28 | self.currentbutton = 0 29 | self.num = 4 #### #get number of images ie 'num' from registration 2 30 | self.status = [] #### #list of click status of 12 buttons 31 | 32 | for i in range(12): 33 | self.status.append(False) 34 | 35 | 36 | 37 | def setupUi(self, imageselect): 38 | imageselect.setObjectName(_fromUtf8("imageselect")) 39 | imageselect.resize(617, 363) 40 | self.scrollArea = QtGui.QScrollArea(imageselect) 41 | self.scrollArea.setGeometry(QtCore.QRect(0, 0, 617, 300)) 42 | self.scrollArea.setMinimumSize(QtCore.QSize(617, 0)) 43 | self.scrollArea.setMaximumSize(QtCore.QSize(617, 300)) 44 | self.scrollArea.setWidgetResizable(True) 45 | self.scrollArea.setObjectName(_fromUtf8("scrollArea")) 46 | self.scrollAreaWidgetContents = QtGui.QWidget() 47 | self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 598, 543)) 48 | self.scrollAreaWidgetContents.setObjectName(_fromUtf8("scrollAreaWidgetContents")) 49 | self.gridLayout_2 = QtGui.QGridLayout(self.scrollAreaWidgetContents) 50 | self.gridLayout_2.setHorizontalSpacing(25) 51 | self.gridLayout_2.setVerticalSpacing(15) 52 | self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) 53 | 54 | 55 | #********************************extracting 12 images from Database and saving them in a list************************** 56 | self.imageList = [] 57 | try: 58 | self.db=mysql.connector.connect(host="localhost", database="python_mysql",user="root",password="2864") 59 | self.cursor=self.db.cursor() 60 | for i in range(12): 61 | self.cursor.execute("select * from image_data where img_id=%s",(i+1,)) 62 | rows=self.cursor.fetchone() 63 | #print(rows[1]) 64 | self.imageList.append(rows[1]) 65 | #print(self.imageList[i]) 66 | 67 | except Error as e: 68 | print(e) 69 | 70 | finally: 71 | self.cursor.close() 72 | self.db.close() 73 | 74 | #****************************************************creating 12 icons for 12 push buttons**************************** 75 | iconList = [] 76 | for i in range(12): 77 | iconList.append(QtGui.QIcon()) 78 | iconList[i].addPixmap(QtGui.QPixmap(_fromUtf8(self.imageList[i])), QtGui.QIcon.Normal, QtGui.QIcon.Off) 79 | 80 | #****************************************************creating 12 push buttons***************************************** 81 | self.imageButton = [] 82 | x=0 83 | y=0 84 | z=0 85 | u=0 86 | j=0 87 | for i in range(12): 88 | self.img = QtGui.QPushButton(self.scrollAreaWidgetContents) 89 | if ((i==0) or (i==1) or (i==2)): 90 | self.img.setGeometry(QtCore.QRect(10+x, 20, 170, 120)) 91 | x=x+185 92 | self.gridLayout_2.addWidget(self.img, 0, i, 1, 1) 93 | if ((i==3) or (i==4) or (i==5)): 94 | self.img.setGeometry(QtCore.QRect(10+y, 150, 170, 120)) 95 | y=y+185 96 | self.gridLayout_2.addWidget(self.img, 1, i-3, 1, 1) 97 | if ((i==6) or (i==7) or (i==8)): 98 | self.img.setGeometry(QtCore.QRect(10+z, 280, 170, 120)) 99 | z=z+185 100 | self.gridLayout_2.addWidget(self.img, 2, i-6, 1, 1) 101 | if ((i==9) or (i==10) or (i==11)): 102 | self.img.setGeometry(QtCore.QRect(10+u, 410, 170, 120)) 103 | u=u+185 104 | self.gridLayout_2.addWidget(self.img, 3, i-9, 1, 1) 105 | self.img.setMinimumSize(QtCore.QSize(170, 120)) 106 | self.img.setMaximumSize(QtCore.QSize(170, 120)) 107 | self.img.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) 108 | self.img.setText(_fromUtf8("")) 109 | self.img.setIcon(iconList[i]) 110 | self.img.setIconSize(QtCore.QSize(180, 100)) 111 | self.img.setCheckable(True) 112 | self.img.setFlat(True) 113 | self.img.setObjectName(_fromUtf8("img1")) 114 | self.gridLayout_2.addWidget(self.img, 0, 0, 1, 1) 115 | self.imageButton.append(self.img) 116 | #----------------------------------------------------------------------------------------------------------------------# 117 | 118 | self.scrollArea.setWidget(self.scrollAreaWidgetContents) 119 | self.open = QtGui.QPushButton(imageselect) 120 | self.open.setGeometry(QtCore.QRect(390, 540, 101, 31)) 121 | font = QtGui.QFont() 122 | font.setPointSize(10) 123 | font.setBold(True) 124 | font.setWeight(75) 125 | self.open.setFont(font) 126 | self.open.setObjectName(_fromUtf8("open")) 127 | self.verticalScrollBar = QtGui.QScrollBar(imageselect) 128 | self.verticalScrollBar.setGeometry(QtCore.QRect(600, 0, 20, 591)) 129 | self.verticalScrollBar.setOrientation(QtCore.Qt.Vertical) 130 | self.verticalScrollBar.setObjectName(_fromUtf8("verticalScrollBar")) 131 | self.retranslateUi(imageselect) 132 | 133 | self.open.clicked['bool'].connect(self.printstatus) 134 | 135 | # for j in range(12): 136 | # print(j) 137 | # self.currentbutton = j 138 | # self.imageButton[j].clicked['bool'].connect(self.updateState) 139 | 140 | self.imageButton[0].clicked['bool'].connect(self.updateStatus0) 141 | self.imageButton[1].clicked['bool'].connect(self.updateStatus1) 142 | self.imageButton[2].clicked['bool'].connect(self.updateStatus2) 143 | self.imageButton[3].clicked['bool'].connect(self.updateStatus3) 144 | self.imageButton[4].clicked['bool'].connect(self.updateStatus4) 145 | self.imageButton[5].clicked['bool'].connect(self.updateStatus5) 146 | self.imageButton[6].clicked['bool'].connect(self.updateStatus6) 147 | self.imageButton[7].clicked['bool'].connect(self.updateStatus7) 148 | self.imageButton[8].clicked['bool'].connect(self.updateStatus8) 149 | self.imageButton[9].clicked['bool'].connect(self.updateStatus9) 150 | self.imageButton[10].clicked['bool'].connect(self.updateStatus10) 151 | self.imageButton[11].clicked['bool'].connect(self.updateStatus11) 152 | 153 | 154 | QtCore.QMetaObject.connectSlotsByName(imageselect) 155 | 156 | #******************updateStatus changes the status of the button,true if clicked and false if double clicked************ 157 | def updateStatus0(self,stat): 158 | self.status[0] = stat 159 | self.check(stat) 160 | 161 | def updateStatus1(self,stat): 162 | self.status[1] = stat 163 | self.check(stat) 164 | 165 | def updateStatus2(self,stat): 166 | self.status[2] = stat 167 | self.check(stat) 168 | 169 | def updateStatus3(self,stat): 170 | self.status[3] = stat 171 | self.check(stat) 172 | 173 | def updateStatus4(self,stat): 174 | self.status[4] = stat 175 | self.check(stat) 176 | 177 | def updateStatus5(self,stat): 178 | self.status[5] = stat 179 | self.check(stat) 180 | 181 | def updateStatus6(self,stat): 182 | self.status[6] = stat 183 | self.check(stat) 184 | 185 | def updateStatus7(self,stat): 186 | self.status[7] = stat 187 | self.check(stat) 188 | 189 | def updateStatus8(self,stat): 190 | self.status[8] = stat 191 | self.check(stat) 192 | 193 | def updateStatus9(self,stat): 194 | self.status[9] = stat 195 | self.check(stat) 196 | 197 | def updateStatus10(self,stat): 198 | self.status[10] = stat 199 | self.check(stat) 200 | 201 | def updateStatus11(self,stat): 202 | self.status[11] = stat 203 | self.check(stat) 204 | 205 | #*********check func increases 'clicks' if button is single clicked, decreases 'clicks' if button is double ckicked***** 206 | def check(self,stat): 207 | if stat==True: 208 | self.clicks = self.clicks+1 209 | else: 210 | self.clicks = self.clicks-1 211 | if self.clicks == self.num: 212 | self.disableUnckecked(True) 213 | else: 214 | self.disableUnckecked(False) 215 | #print(stat,self.clicks," ",end = " ") 216 | 217 | #*************************************if image limit is reached, disable unckecked images******************************* 218 | def disableUnckecked(self,bl): 219 | for k in range(12): 220 | if self.status[k]==False: 221 | self.imageButton[k].setDisabled(bl) 222 | 223 | def retranslateUi(self, imageselect): 224 | imageselect.setWindowTitle(_translate("imageselect", "Form", None)) 225 | self.open.setText(_translate("imageselect", "Open", None)) 226 | 227 | def printstatus(self): 228 | print(self.status) 229 | 230 | 231 | if __name__ == '__main__': 232 | app = QtGui.QApplication(sys.argv) 233 | mainWindow = Ui_imageselect() 234 | mainWindow.show() 235 | sys.exit(app.exec()) 236 | 237 | --------------------------------------------------------------------------------