Pymongo and qt5 designer form - Need code for buttons to move to previous and next documents

Hello everyone,

Greetings from Brazil! I’m a beginner programmer learning Python 3. I created a form in Qt5 Designer to navigate through my mongoDB database.

The insert document form works great. Also, I was able to create 50% of the navigation form funcionality. It has four buttons to display documents: First, Previous, Next and Last. The buttons for First and Last document work, but I’m strugging with Previous and Next.

They need to step forward and back in the collection every time the buttons are pressed and I can’t figure out how to do this. Suggestions are welcome! Please refer to my code below. I really appreciate your time and help. Thanks a lot.

Best regards.

What I have tried:

import sys
import pymongo.mongo_client
from PyQt5 import QtCore, QtWidgets


connection = pymongo.MongoClient('localhost', 27017)
database = connection['bremi691_ead']
collection = database['usuarios']


global first_doc
global previous_doc
global next_doc
global last_doc


class Ui_Dialog(object):

    def __init__(self):
        self.lineEdit_name = QtWidgets.QLineEdit(Dialog)
        self.lineEdit_email = QtWidgets.QLineEdit(Dialog)
        self.lineEdit_pwd = QtWidgets.QLineEdit(Dialog)
        self.lineEdit_market = QtWidgets.QLineEdit(Dialog)

        self.pushButton_first = QtWidgets.QPushButton(Dialog)
        self.pushButton_previous = QtWidgets.QPushButton(Dialog)
        self.pushButton_next = QtWidgets.QPushButton(Dialog)
        self.pushButton_last = QtWidgets.QPushButton(Dialog)

    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(448, 300)

        self.lineEdit_name.setGeometry(QtCore.QRect(130, 50, 241, 21))
        self.lineEdit_name.setInputMethodHints(QtCore.Qt.ImhUppercaseOnly)
        self.lineEdit_name.setObjectName("lineEdit_name")

        self.lineEdit_email.setGeometry(QtCore.QRect(130, 90, 191, 21))
        self.lineEdit_email.setInputMethodHints(QtCore.Qt.ImhEmailCharactersOnly)
        self.lineEdit_email.setObjectName("lineEdit_email")

        self.lineEdit_pwd.setGeometry(QtCore.QRect(130, 130, 131, 21))
        self.lineEdit_pwd.setInputMethodHints(QtCore.Qt.ImhSensitiveData | QtCore.Qt.ImhUppercaseOnly)
        self.lineEdit_pwd.setObjectName("lineEdit_pwd")

        self.lineEdit_market.setGeometry(QtCore.QRect(130, 170, 131, 21))
        self.lineEdit_market.setInputMethodHints(QtCore.Qt.ImhUppercaseOnly)
        self.lineEdit_market.setObjectName("lineEdit_market")

        self.pushButton_first.setGeometry(QtCore.QRect(70, 240, 61, 28))
        self.pushButton_first.setObjectName("pushButton_first")
        self.pushButton_first.clicked.connect(ShowFirst)

        self.pushButton_previous.setGeometry(QtCore.QRect(150, 240, 61, 28))
        self.pushButton_previous.setObjectName("pushButton_previous")
        self.pushButton_previous.clicked.connect(ShowPrevious)

        self.pushButton_next.setGeometry(QtCore.QRect(230, 240, 61, 28))
        self.pushButton_next.setObjectName("pushButton_next")
        self.pushButton_next.clicked.connect(ShowNext)

        self.pushButton_last.setGeometry(QtCore.QRect(310, 240, 61, 28))
        self.pushButton_last.setObjectName("pushButton_last")
        self.pushButton_last.clicked.connect(ShowLast)

        self.retranslateUi(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.pushButton_first.setText(_translate("Dialog", "First"))
        self.pushButton_previous.setText(_translate("Dialog", "Previous"))
        self.pushButton_next.setText(_translate("Dialog", "Next"))
        self.pushButton_last.setText(_translate("Dialog", "Last"))

        ShowFirst()


def ShowFirst():
    global first_doc
    coll = collection.find().sort("nome", 1).limit(1)
    for first_doc in coll: ('{0}'.format(first_doc['nome']))
    ui.lineEdit_name.setText(str(first_doc['nome']))
    ui.lineEdit_email.setText(str(first_doc['email'])),
    ui.lineEdit_pwd.setText(str(first_doc['senha'])),
    ui.lineEdit_market.setText(str(first_doc['como_chegou']))
    coll.close()


def ShowPrevious():
    print("Insert code to move to previous document")


def ShowNext():
    print("Insert code to move to next document")


def ShowLast():
    global last_doc
    coll = collection.find().sort("nome", -1).limit(1)
    for last_doc in coll: ('{0}'.format(last_doc['nome']))
    ui.lineEdit_name.setText(str(last_doc['nome']))
    ui.lineEdit_email.setText(str(last_doc['email'])),
    ui.lineEdit_pwd.setText(str(last_doc['senha'])),
    ui.lineEdit_market.setText(str(last_doc['como_chegou']))
    coll.close()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

Hi @JC_Carmo,

Essentially this is similar to performing a pagination, although in your case it’s just one document being displayed at a time.

You need to record a unique id for the document on display to keep track of where the display is at. For previous or next action, you could retrieve a document from the database with either previous/next id in the collection. This should be similar to an example in Using Range Queries just without the skip and limit.

Depending on your use case, you could also retrieve a batch of documents (i.e. 20) to prevent the application running single query to the database for every click action.

Regards,
Wan.

1 Like

Thanks for your feed-back, Wan! I am going to try your suggestion. Best regards and stay well. :slight_smile: