Build a Remarkably Awesome Interactive Calendar With Python

ZennDogg
13 min readMay 10, 2021
Nice, but not functional.

About two years ago, when I first started teaching myself python, I really wanted an interactive calendar to display on my monitor. I ran across Python’s calendar module. I liked the look and size of the calendar, but it didn’t do anything but sit there. So, I continued my quest.

Like many of you, my first GUI package was Tkinter. I tried designing a calendar with it but became completely overwhelmed. I then learned that PyQt5 has a QCalendarWidget for building a calendar. At the time, I wanted something small and unobtrusive, and the QcalendarWidget was much too big. Also, I wasn’t versed in PyQt5 at all. Still overwhelmed.

I finally shelved the idea of a calendar and designed a small GUI that shows the current day, date, and time.

Here it is two years later. I’m now adequate with using PyQt5 and can get it to do almost anything I need. Well, I decided I needed an appointment calendar, where I could click on a date in the future, fill in the normal appointment parameters, and display upcoming appointments.

Time to Revisit QCalendarWidget

Click on today’s date or any date in the future and an appointment window opens for entering appointment information.

We’ll start with the import statements.

import sys, os
import pandas as pd
from datetime import datetime
from pymongo import MongoClient
from PyQt5.QtCore import QDate, Qt, QRect
from PyQt5.QtGui import (
QFont,
QColor,
QBrush,
QPainter,
QTextCharFormat,

)
from PyQt5.QtWidgets import (
QLabel,
QWidget,
QTextEdit,
QApplication,
QTableWidget,
QCalendarWidget,
QTableWidgetItem,
)

As usual, my database of choice is MongoDb, so MongoClient must be imported from Pymongo. The next three lines of code initializes the database.

client = MongoClient("localhost", 27017)
db = client["mydb"]
coll = db["appointments"]

Since we’re building a calendar, we need a calendar class.

class Calendar(QCalendarWidget):    def __init__(self, parent=None):
super(Calendar, self).__init__(parent)

The next class pulls all appointments from the database, sorts the entries in Date order, and ignores all appointments before the current date. Also, the year is dropped from the date for ease in displaying.

class Appointments():

def appointments(self):
appts = []
now = datetime.now()
today = now.strftime('%m-%d-%Y')

data = coll.find({}, {'_id': 0, 'date': 1, 'time': 1, 'place': 1, 'note': 1}).sort('date')
for _d in data:
if _d['date'] < today:
pass
else:
date, time, place, note = _d['date'][:5], _d['time'], _d['place'], _d['note']
appts.append([date, time, place, note])
return appts

Now we write the class for the GUI. Here we define the where and size of the window and initialize class variables.

class Example(QWidget):    def __init__(self):
super(Example, self).__init__()
self.initUI()


def initUI(self):
self.left = 1138
self.top = 30
self.width = 302
self.height = 370
self.appointments = Appointments()
self.cal = QCalendarWidget( self )
format = QTextCharFormat()

Next, I define the window itself. If you’ve read any of my other articles, you’ll recall I have a certain theme I pursue when designing my graphic displays (all black with no window header, borders, or scroll bars). That code is:

self.setWindowFlags(Qt.FramelessWindowHint)
self.setGeometry(self.left,self.top,self.width,self.height)
self.setAutoFillBackground(True)
p = self.palette()
p.setColor(self.backgroundRole(), Qt.black)
self.setPalette(p)

This calendar has one button for exiting the program. I use the same style for this type of button in all my graphic projects. The style is defined as follows:

qdim = "QPushButton {color: rgba(54, 136, 200, 250); background-color: black; }"

Next, we define the fonts that we will use.

canda_10 = QFont("Candalara", 10)
canda_11 = QFont( "Candalara", 11 )
segoe_9 = QFont('Segoe UI', 9)

The stock PyQt5 calendar uses red numbers to designate weekend days. The red is too bright for my theme, so I needed to change that.

format   = self.cal.weekdayTextFormat( Qt.Saturday)
format.setForeground( QBrush( Qt.darkCyan, Qt.SolidPattern ) )
self.cal.setWeekdayTextFormat( Qt.Saturday, format )
self.cal.setWeekdayTextFormat( Qt.Sunday, format )

The stock calendar also lists the week numbers on the left of the Sunday column. I didn’t want that. Also, note the size of the calendar widget itself. This is the smallest it can get using the 3-letter day format (default). I assume it can be made even smaller with single-letter day names. Consequently, it will need to be larger using full names for the days. I also didn’t want the grid lines to show.

self.cal.setVerticalHeaderFormat( self.cal.NoVerticalHeader )
self.cal.setGridVisible(False)
self.cal.setGeometry(0, 0, 292, 221)
self.cal.setFont(segoe_9)

The calendar stylesheet is where most of the customizing takes place. The first setting gives the widget its black background, date highlight color, date highlight background color, and font color. The second setting alters the background of the day name header. The third setting customizes the month, year header, and the last two lines change the arrow graphics used for selecting the previous/next month.

self.cal.setStyleSheet(
"QCalendarWidget QAbstractItemView{background-color: black; color: rgba(162,201,229,255); selection-background-color: rgb(20,20,20); selection-color: rgb(200,150,255); selection-border: 1px solid black;}"
"QCalendarWidget QWidget{alternate-background-color: rgb(20, 20, 20); color: gray;}" "QCalendarWidget QToolButton{background-color: black; color: rgb(125,125,125); font-size: 14px; font: bold; width: 70px; border: none;}" "QCalendarWidget QToolButton#qt_calendar_prevmonth{qproperty-icon: url(left_arrow.png);}" "QCalendarWidget QToolButton#qt_calendar_nextmonth{qproperty-icon: url(right_arrow.png);}"
)

Next, we initialize the exit button and the function that runs when a date is clicked. This is where we use the qdim style variable.

self.button = QPushButton(self)
self.button.setStyleSheet(qdim)
self.button.setFont(canda_11)
self.button.setText("EXIT")
self.button.setGeometry(10, 240, 281, 90)
self.button.clicked.connect(self.exit)
self.cal.clicked[QDate].connect(self.showDate)

The section on the GUI window that shows the upcoming appointments is a table. I designed it to show the next three appointments. The table is scrollable. Again, I wanted no header, no scroll bars, and no indexes.

self.appt_table = QTableWidget( self )
self.appt_table.setGeometry( QRect( 10, 240, 281, 90 ) )
self.appt_table.setStyleSheet(
"QTableWidget {color: rgb(135,135,135); background-color: black; border: none;}"
)
self.appt_table.horizontalHeader().hide()
self.appt_table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.appt_table.setFont( canda_10 )
self.appt_table.verticalHeader().setVisible( False )

Now we get the data from the database and input it into a Pandas DataFrame.

data = self.appointments.appointments()
df = pd.DataFrame(data)
self.display_data(df)
self.show()

The third line above calls a function, display_data(df). This builds the table for display from the Pandas DataFrame.

def display_data(self, var):
self.appt_table.setColumnCount( len( var.columns ) )
self.appt_table.setRowCount( len( var.index ) )

for i in range( len( var.index ) ):
for j in range( len( var.columns ) ):
self.appt_table.setItem( i, j, QTableWidgetItem( str( var.iat[i, j] ) ) )
self.appt_table.resizeColumnsToContents()

When a date in the calendar is clicked, the function showDate() is called. Recall that we don’t want to see past appointments. If a past date is clicked on, nothing happens (besides the new date being highlighted). If the present or future date is clicked, a new window is called. The code for showDate() follows:

def showDate(self, date):
now = QDate.currentDate()
select_date = self.cal.selectedDate()
if select_date < now:
pass
else:
string_date = str(select_date.toPyDate())
self.event_form(string_date)

The hardest part for me on this function was getting the variables now and select_date to be of the same type for comparison. Initializing the variable now as a QDate object instead of a datetime object solved that problem. The last line of the function above calls another function, event_form(), with the selected date being passed as a string. The date string is saved as a text file for future use. I couldn’t find very much about .toPyDate(), but it works in this case.

The next function writes the date string to a text file and runs the Event_Form file.

def event_form(self, string_date):
with open('string_date.txt', 'w') as file:
file.write(string_date)
os.system( r"start /min python event_form.pyw" )

This function draws the two horizontal lines being used as section separators.

def paintEvent(self, e):
self.painter = QPainter( self )
self.painter.begin( self )
self.painter.setPen(QColor(75, 75, 75))
self.painter.drawLine(50, 230, 250, 230)
self.painter.drawLine(50, 340, 250, 340)
self.painter.end()

We must not forget to define an exit function.

def exit(self):
self.close()

And finally:

if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

So far, this is exactly what I wanted a calendar to be. Now that this was done, I needed to build the Event_Form. It’s a separate file so, again, we start with the import statements.

The Event Form

import sys
from pymongo import MongoClient
from PyQt5.QtCore import QDate, Qt
from PyQt5.QtGui import (
QPen,
QFont,
QColor,
QBrush,
QPainter,
)
from PyQt5.QtWidgets import (
QLabel,
QWidget,
QLineEdit,
QTextEdit,
QCheckBox,
QComboBox,
QApplication,
)

Then, initialize the database.

client = MongoClient("localhost", 27017)
db = client["mydb"]
coll = db["appointments"]

Now to start the GUI class. Notice it begins almost the same as the calendar GUI.

class EventForm(QWidget):
def __init__(self):
super(EventForm, self).__init__()
self.initUI()

def initUI(self):
self.left = 1139
self.top = 253
self.width = 301
self.height = 370
self.setWindowFlags(Qt.FramelessWindowHint)
self.setGeometry(self.left,self.top,self.width,self.height)
self.setAutoFillBackground(True)
p = self.palette()
p.setColor(self.backgroundRole(), Qt.black)
self.setPalette(p)
qdim = "QPushButton {color: rgba(54, 136, 200, 250); background-color: black; }" segoe_9 = QFont( 'Segoe UI', 9 )
segoe_16 = QFont( "Segoe UI", 16 )
canda_10 = QFont( "Candalara", 10 )
canda_11 = QFont( "Candalara", 11 )
canda_12 = QFont( "Candalara", 12 )

I decided on a combo box to display appointment times (every half hour) instead of typing in the time manually. To populate the combo box requires a list.

times = [
'All Day','5:00 AM', '5:30 AM', '6:00 AM', '6:30 AM',
'7:00 AM', '7:30 AM', '8:00 AM', '8:30 AM', '9:00 AM',
'9:30 AM', '10:00 AM', '10:30 AM', '11:00 AM', '11:30 AM',
'Noon', '12:30 PM', '1:00 PM', '1:30 PM','2:00 PM',
'2:30 PM', '3:00 PM', '3:30 PM', '4:00 PM', '4:30 PM',
'5:00 PM', '5:30 PM', '6:00 PM',
]

These next lines of code reads the date string from the text file. The string is then formatted for display on the form and entry to the database.

with open('string_date.txt', "r") as file:
data = file.read()
num = datetime.strptime(data, '%Y-%m-%d')
day = str(num.strftime( '%A' ))
date = str(num.strftime('%m-%d-%Y'))

At the top of the form are the day name and the date that was clicked on the calendar. The code for this label is:

self.date_data = QLabel(self)
self.date_data.setGeometry( 0, 15, 301, 40 )
self.date_data.setStyleSheet( "QLabel {color: rgba(125,125,125,255); background-color: black;}" )
self.date_data.setFont( segoe_16 )
self.date_data.setAlignment(Qt.AlignCenter)
self.date_data.setText(day + " " + date)

The next three labels display the text “Time”, “Place”, and “Note”.

self.time_label = QLabel(self)
self.time_label.setGeometry(15, 70, 80, 40)
self.time_label.setStyleSheet( "QLabel {color: rgba(125,125,125,255); background-color: black;}" )
self.time_label.setFont(canda_11)
self.time_label.setText("Time")
self.place_label = QLabel(self)
self.place_label.setGeometry(15, 115, 80, 40)
self.place_label.setStyleSheet( "QLabel {color: rgba(125,125,125,255); background-color: black;}" )
self.place_label.setFont(canda_11)
self.place_label.setText("Place")

self.note_label = QLabel(self)
self.note_label.setGeometry( 15, 160, 80, 40 )
self.note_label.setStyleSheet( "QLabel {color: rgba(125,125,125,255); background-color: black;}" )
self.note_label.setFont( canda_11 )
self.note_label.setText( "Note" )

Next is the code for the combo box of time choices using the list of times we wrote earlier.

self.time_cbox = QComboBox( self )
self.time_cbox.setGeometry( 70, 75, 100, 30 )
self.time_cbox.setStyleSheet( "QComboBox {color: rgba(125,125,125,255); background-color: black;}" )
self.time_cbox.setFont( canda_11 )
for time in times:
self.time_cbox.addItem(time)
self.time_cbox.currentIndexChanged.connect(self.selectionchange)

We need a place to type in the appointment location and any information about that appointment.

self.place_edit = QLineEdit( self )
self.place_edit.setGeometry(70, 120, 215, 30 )
self.place_edit.setStyleSheet( "QLineEdit {color: rgba(125,125,125,255); background-color: rgba(29, 29, 29, 150); border: none;}" )
self.place_edit.setFont( canda_12 )

self.note_edit = QTextEdit(self)
self.note_edit.setGeometry( 70, 165, 215, 80 )
self.note_edit.setStyleSheet( "QTextEdit {color: rgba(125,125,125); background-color: rgba(29, 29, 29, 150); border: none;}" )
self.note_edit.setFont( canda_12 )

The form has three buttons; Save, Exit, Save & Exit. The buttons are initialized as follows:

self.save = QPushButton(self)
self.save.setStyleSheet(qdim)
self.save.setFont(canda_10)
self.save.setText("SAVE")
self.save.setGeometry(120, 295, 60, 50)
self.save.clicked.connect(self.save)
self.exit = QPushButton(self)
self.exit.setStyleSheet(qdim)
self.exit.setFont(canda_10)
self.exit.setText("EXIT")
self.exit.setGeometry(210, 295, 60, 50)
self.exit.clicked.connect(self.exit)
self.sav-exit = QPushButton(self)
self.sav-exit.setStyleSheet(qdim)
self.sav-exit.setFont(canda_10)
self.sav-exit.setText("SAVE\nEXIT")
self.sav-exit.setGeometry(10, 240, 281, 90)
self.sav-exit.clicked.connect(self.save_exit)
---------------------------------------------Hint: Write a generic button function to shorten your code. For example:def qtbutton(self, name, x, y, w, h, style, font, title, connection):
self.name = QPushButton(self)
self.name.setStyleSheet(style)
self.name.setFont(font)
self.name.setText(title)
self.name.setGeometry(x, y, w, h)
self.name.clicked.connect(connection)
Then you can rewrite the save button function like this:qtbutton(self, 'save', 120, 295, 60, 50, qdim, canda_10, "SAVE", self.save)

When choosing a time from the combo box, the function, selectionchange(), is called. Since the selected date is kept in memory, we don’t have to initialize a variable. I use the function to set the focus on the next text entry box.

def selectionchange(self):
self.place_edit.setFocus()

Just like earlier in this article, we need a function to draw the two separator lines.

def paintEvent(self, e):
self.painter = QPainter( self )
self.painter.begin( self )
self.painter.setPen(QColor(75, 75, 75))
self.painter.drawLine(15, 65, 285, 65)
self.painter.drawLine(15, 270, 285, 270 )
self.painter.end()
--------------------------------------------------
Hint: The paintEvent() function is used twice in this project. Write a function to shorten the above code to one line. For example:
def qtpainter(self, color, x, y, w, h):
self.painter = QPainter( self )
self.painter.begin( self )
self.painter.setPen(QColor( color )
self.painter.drawLine(15, 65, 285, 65)
self.painter.end()
To draw a line:qtpainter(self, QColor(75, 75, 75), 15, 65, 285, 65)

The save() and save_exit() functions use almost the same coding. So as not to repeat myself, the function repeat() was created. Using [-10:] removes the day name from the string leaving just the date.

def repeat(self):
date = self.date_data.text()[-10:]
time = self.time_cbox.currentText()
place = self.place_edit.text()
note = self.note_edit.toPlainText()
coll.insert_one({'date': date, "time": time, 'place': place, 'note': note})

Now for the three button functions.

def save(self):
data = self.repeat()
self.place_edit.clear()
self.note_edit.clear()

def save_exit(self):
data = self.repeat()
self.exit()

def exit(self):
self.close()

And finally:

if __name__ == "__main__":
app = QApplication(sys.argv)
ex = EventForm()
ex.show()
sys.exit(app.exec_())

If you enjoy reading stories like these and want to support me as a writer, consider subscribing to Medium for $5 a month. As a member, you have unlimited access to stories on Medium. If you sign up using my link, I’ll earn a small commission.

The two files in their entirety:

# calendar.pywimport sys, os
import pandas as pd
from datetime import datetime
from pymongo import MongoClient
from PyQt5.QtCore import QDate, Qt, QRect
from PyQt5.QtGui import (
QFont,
QColor,
QBrush,
QPainter,
QTextCharFormat,

)
from PyQt5.QtWidgets import (
QLabel,
QWidget,
QTextEdit,
QApplication,
QTableWidget,
QCalendarWidget,
QTableWidgetItem,
)
client = MongoClient("localhost", 27017)
db = client["mydb"]
coll = db["appointments"]
class Calendar(QCalendarWidget): def __init__(self, parent=None):
super(Calendar, self).__init__(parent)
class Appointments():

def appointments(self):
appts = []
now = datetime.now()
today = now.strftime('%m-%d-%Y')

data = coll.find({}, {'_id': 0, 'date': 1, 'time': 1, 'place': 1, 'note': 1}).sort('date')
for _d in data:
if _d['date'] < today:
pass
else:
date, time, place, note = _d['date'][:5], _d['time'], _d['place'], _d['note']
appts.append([date, time, place, note])
return appts
class Example(QWidget): def __init__(self):
super(Example, self).__init__()
self.initUI()


def initUI(self):
self.left = 1138
self.top = 30
self.width = 302
self.height = 370
self.appointments = Appointments()
self.cal = QCalendarWidget( self )
format = QTextCharFormat()
self.setWindowFlags(Qt.FramelessWindowHint)
self.setGeometry(self.left,self.top,self.width,self.height)
self.setAutoFillBackground(True)
p = self.palette()
p.setColor(self.backgroundRole(), Qt.black)
self.setPalette(p)
qdim = "QPushButton {color: rgba(54, 136, 200, 250); background-color: black; }"
canda_10 = QFont("Candalara", 10)
canda_11 = QFont( "Candalara", 11 )
segoe_9 = QFont('Segoe UI', 9)
format = self.cal.weekdayTextFormat( Qt.Saturday)
format.setForeground(QBrush( Qt.darkCyan, Qt.SolidPattern))
self.cal.setWeekdayTextFormat( Qt.Saturday, format )
self.cal.setWeekdayTextFormat( Qt.Sunday, format )
self.cal.setVerticalHeaderFormat(self.cal.NoVerticalHeader)
self.cal.setGridVisible(False)
self.cal.setGeometry(0, 0, 292, 221)
self.cal.setFont(segoe_9)
self.cal.setStyleSheet(
"QCalendarWidget QAbstractItemView{background-color:
black; color: rgba(162,201,229,255); selection-background-color: rgb(20,20,20); selection-color: rgb(200,150,255); selection-border: 1px solid black;}"
"QCalendarWidget QWidget{alternate-background-color:
rgb(20, 20, 20); color: gray;}"
"QCalendarWidget QToolButton{background-color: black;
color: rgb(125,125,125); font-size: 14px; font: bold; width: 70px; border: none;}"
"QCalendarWidget QToolButton#qt_calendar_
prevmonth{qproperty-icon: url(left_arrow.png);}"
"QCalendarWidget QToolButton#qt_calendar_
nextmonth{qproperty-icon: url(right_arrow.png);}"
)
self.button = QPushButton(self)
self.button.setStyleSheet(qdim)
self.button.setFont(canda_11)
self.button.setText("EXIT")
self.button.setGeometry(10, 240, 281, 90)
self.button.clicked.connect(self.exit)
self.cal.clicked[QDate].connect(self.showDate) self.appt_table = QTableWidget( self )
self.appt_table.setGeometry( QRect( 10, 240, 281, 90 ) )
self.appt_table.setStyleSheet(
"QTableWidget {color: rgb(135,135,135); background-color: black; border: none;}"
)
self.appt_table.horizontalHeader().hide()
self.appt_table.setVerticalScrollBarPolicy(
Q
t.ScrollBarAlwaysOff)
self.appt_table.setFont( canda_10 )
self.appt_table.verticalHeader().setVisible( False )
data = self.appointments.appointments()
df = pd.DataFrame(data)
self.display_data(df)
self.show()
def display_data(self, var):
self.appt_table.setColumnCount( len( var.columns ) )
self.appt_table.setRowCount( len( var.index ) )

for i in range( len( var.index ) ):
for j in range( len( var.columns ) ):
self.appt_table.setItem( i, j, QTableWidgetItem( str( var.iat[i, j] ) ) )
self.appt_table.resizeColumnsToContents()
def showDate(self, date):
now = QDate.currentDate()
select_date = self.cal.selectedDate()
if select_date < now:
pass
else:
string_date = str(select_date.toPyDate())
self.event_form(string_date)
def event_form(self, string_date):
with open('string_date.txt', 'w') as file:
file.write(string_date)
os.system( r"start /min python event_form.pyw" )

def paintEvent(self, e):
self.painter = QPainter( self )
self.painter.begin( self )
self.painter.setPen(QColor(75, 75, 75))
self.painter.drawLine(50, 230, 250, 230)
self.painter.drawLine(50, 340, 250, 340)
self.painter.end()
def exit(self):
self.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
# event_form.pywimport sys
from datetime import datetime
from pymongo import MongoClient
from PyQt5.QtCore import QDate, Qt
from PyQt5.QtGui import (
QPen,
QFont,
QColor,
QBrush,
QPainter,
)
from PyQt5.QtWidgets import (
QLabel,
QWidget,
QLineEdit,
QTextEdit,
QCheckBox,
QComboBox,
QApplication,
)


client = MongoClient("localhost", 27017)
db = client["mydb"]
coll = db["appointments"]



class EventForm(QWidget):
def __init__(self):
super(EventForm, self).__init__()
self.initUI()

def initUI(self):
self.left = 1139
self.top = 253
self.width = 301
self.height = 370

self.setWindowFlags(Qt.FramelessWindowHint)
self.setGeometry(self.left,self.top,self.width,self.height)
self.setAutoFillBackground(True)
p = self.palette()
p.setColor(self.backgroundRole(), Qt.black)
self.setPalette(p)
qdim = "QPushButton {color: rgba(54, 136, 200, 250); background-color: black; }" segoe_9 = QFont( 'Segoe UI', 9 )
segoe_16 = QFont( "Segoe UI", 16 )
canda_10 = QFont( "Candalara", 10 )
canda_11 = QFont( "Candalara", 11 )
canda_12 = QFont( "Candalara", 12 )

times = [
'All Day','5:00 AM', '5:30 AM', '6:00 AM', '6:30 AM',
'7:00 AM', '7:30 AM', '8:00 AM', '8:30 AM', '9:00 AM',
'9:30 AM', '10:00 AM', '10:30 AM', '11:00 AM',
'11:30 AM', 'Noon', '12:30 PM', '1:00 PM', '1:30 PM',
'2:00 PM', '2:30 PM', '3:00 PM', '3:30 PM', '4:00 PM',
'4:30 PM', '5:00 PM', '5:30 PM', '6:00 PM',
]

with open('string_date.txt', "r") as file:
data = file.read()
day = str(num.strftime( '%A' ))
date = str(num.strftime('%m-%d-%Y'))
self.date_data = QLabel(self)
self.date_data.setGeometry( 0, 15, 301, 40 )
self.date_data.setStyleSheet( "QLabel {color: rgba(125,125,125,255); background-color: black;}" )
self.date_data.setFont( segoe_16 )
self.date_data.setAlignment(Qt.AlignCenter)
self.date_data.setText(day + " " + date)

self.time_label = QLabel(self)
self.time_label.setGeometry(15, 70, 80, 40)
self.time_label.setStyleSheet( "QLabel {color: rgba(125,125,125,255); background-color: black;}" )
self.time_label.setFont(canda_11)
self.time_label.setText("Time")

self.place_label = QLabel(self)
self.place_label.setGeometry(15, 115, 80, 40)
self.place_label.setStyleSheet( "QLabel {color: rgba(125,125,125,255); background-color: black;}" )
self.place_label.setFont(canda_11)
self.place_label.setText("Place")

self.note_label = QLabel(self)
self.note_label.setGeometry( 15, 160, 80, 40 )
self.note_label.setStyleSheet( "QLabel {color: rgba(125,125,125,255); background-color: black;}" )
self.note_label.setFont( canda_11 )
self.note_label.setText( "Note" )
self.time_cbox = QComboBox( self )
self.time_cbox.setGeometry( 70, 75, 100, 30 )
self.time_cbox.setStyleSheet( "QComboBox {color: rgba(125,125,125,255); background-color: black;}" )
self.time_cbox.setFont( canda_11 )
for time in times:
self.time_cbox.addItem(time)
self.time_cbox.currentIndexChanged.connect(self.
selectionchange)
self.place_edit = QLineEdit( self )
self.place_edit.setGeometry(70, 120, 215, 30 )
self.place_edit.setStyleSheet( "QLineEdit {color: rgba(125,125,125,255); background-color: rgba(29, 29, 29, 150); border: none;}" )
self.place_edit.setFont( canda_12 )

self.note_edit = QTextEdit(self)
self.note_edit.setGeometry( 70, 165, 215, 80 )
self.note_edit.setStyleSheet( "QTextEdit {color: rgba(125,125,125); background-color: rgba(29, 29, 29, 150); border: none;}" )
self.note_edit.setFont( canda_12 )
self.save = QPushButton(self)
self.save.setStyleSheet(qdim)
self.save.setFont(canda_10)
self.save.setText("SAVE")
self.save.setGeometry(120, 295, 60, 50)
self.save.clicked.connect(self.save)
self.exit = QPushButton(self)
self.exit.setStyleSheet(qdim)
self.exit.setFont(canda_10)
self.exit.setText("EXIT")
self.exit.setGeometry(210, 295, 60, 50)
self.exit.clicked.connect(self.exit)
self.sav-exit = QPushButton(self)
self.sav-exit.setStyleSheet(qdim)
self.sav-exit.setFont(canda_10)
self.sav-exit.setText("SAVE\nEXIT")
self.sav-exit.setGeometry(10, 240, 281, 90)
self.sav-exit.clicked.connect(self.save_exit)

def selectionchange(self):
self.place_edit.setFocus()
def paintEvent(self, e):
self.painter = QPainter( self )
self.painter.begin( self )
self.painter.setPen(QColor(75, 75, 75))
self.painter.drawLine(15, 65, 285, 65)
self.painter.drawLine(15, 270, 285, 270 )
self.painter.end()

def repeat(self):
date = self.date_data.text()[-10:]
time = self.time_cbox.currentText()
place = self.place_edit.text()
note = self.note_edit.toPlainText()
coll.insert_one({'date': date, "time": time, 'place': place, 'note': note})

def save(self):
data = self.repeat()
self.place_edit.clear()
self.note_edit.clear()

def save_exit(self):
data = self.repeat()
self.exit()

def exit(self):
self.close()



if __name__ == "__main__":
app = QApplication(sys.argv)
ex = EventForm()
ex.show()
sys.exit(app.exec_())

--

--

ZennDogg

Retired military, Retired US Postal Service, Defender of the US Constitution from all enemies, foreign and domestic, Self-taught in python