Разработка кроссплатформенного менеджера виджетов рабочего стола
Интерфейс и функции виджетов, используемые в разработке программные средства. Элементы: часы, календарь, заметки, сервер. Формирование кроссплатформенного менеджера виджетов рабочего стола, обладающего интерфейсом на нескольких операционных системах.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 06.07.2015 |
Размер файла | 210,4 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
«» «Слот при нажатии на 'Управление будильниками'»"»
self.refresh_al_list()
self.dt_edit.setDateTime (QtCore.QDateTime (datetime.datetime.now()))
self.dt_picker_wdg.show()
@QtCore.pyqtSlot()
def dt_pick_ok(self):
«»«Слот при нажатии «Добавить будильник» в выборе даты и коммента будильника»"»
self.add_alarm (self.dt_edit.dateTime().toPyDateTime(), self.cmnt_edit.text())
self.refresh_al_list()
@QtCore.pyqtSlot()
def dt_pick_del(self):
«»«Слот при нажатии «Удалить будильник» в окне будильников»"»
sel = self.al_list.selectedIndexes()
if len(sel) == 1:
al_comm = sel[0].data()
al_comm = al_comm [al_comm.index ('(') + 1: -1]
self.del_alarm (al_comm)
self.refresh_al_list()
@QtCore.pyqtSlot()
def exit(self):
«» «Слот при нажатии кнопки закрытия»"»
self.wm.widget_list.remove(self)
self.hide()
self.destroy()
@QtCore.pyqtSlot()
def change_delta(self):
«» «Слот при нажатии кнопки смены часового пояса»"»
self.d_picker_wdg.show()
@QtCore.pyqtSlot()
def d_pick_ok(self):
«» «Слот при нажатии кнопки ОК смены часового пояса»"»
self.d_picker_wdg.hide()
self.delta = datetime.timedelta (hours=self.d_edit.itemData (self.d_edit.currentIndex()))
self.update()
def add_alarm (self, date_time=None, comment='безымянный'):
«» «Добавление будильника»"»
comment = comment.replace ('\x03\x04', «) # удалим спец-символы, если кто-то надоумился их туда вставить
if comment not in self.alarms.keys():
self.alarms[comment] = date_time
else:
msg = QtGui.QMessageBox(self)
msg.setWindowTitle('Ошибка')
msg.setText ('Будильник <b>%s</b> уже есть'% comment)
msg.show()
def del_alarm (self, comment='безымянный'):
«» «Удаление будильника»"»
if comment in self.alarms.keys():
self.alarms.pop(comment)
def refresh_al_list(self):
self.al_model.clear()
dtnow = datetime.datetime.now()
for al_comm, al_date in sorted (self.alarms.items(), key=lambda x: x[1]):
d_fromat = [' % Y', ' % d % b.', ' % X']
if al_date.year == dtnow.year:
d_fromat.pop(0)
if al_date.month == dtnow.month and al_date.day == dtnow.day:
d_fromat.pop(0)
item = QtGui.QStandardItem (' % s (%s)'% (al_date.strftime (', '.join (d_fromat)), al_comm))
self.al_model.appendRow(item)
def alarm(self):
«»«Воспроизведение звука будильника.
Здеь содержится платформо-зависимый код т.к.
со звуковыми подсистемами qt решили не мудрить.
В Linux требуется sox. ""»
if system() == 'Windows':
self.alarmsnd.play()
elif system() == 'Linux':
QtCore.QProcess.startDetached («play» + self.alarmsnd_path) # требует sox на машине
# следующие 2 метода задают поведение: виджет будет перетаскиваться при перетаскивании мыши
def mousePressEvent (self, event):
«» «Записывает координаты нажатия мыши»"»
if event.button() == QtCore. Qt. LeftButton:
self.grabpoint = event.pos()
self.moveing = True
# up
def mouseMoveEvent (self, event):
«» «Перетаскивает виджет за курсором мыши»"»
if (event.buttons() & QtCore. Qt. LeftButton) and self.moveing:
newx = self.x() + event.pos().x() - self.grabpoint.x()
newy = self.y() + event.pos().y() - self.grabpoint.y()
if 0 <= newx <= (self.wm.max_size.width() - self.width()):
self.move (newx, self.y())
if 0 <= newy <= (self.wm.max_size.height() - self.height()):
self.move (self.x(), newy)
def serialize(self):
«»«Сериализация. Ввиду того, что это PyQt,
стандартные методы не подходят
(c object'ты не сериализуются)""»
return '\x03'.join([self.name,
repr (self.show_notific),
repr (self.show_tray_notific),
repr (self.alarms),
repr (self.delta)])
widgets/calendar/__init__.py
«»»
Виджет календаря
«»»
from PyQt4 import QtCore, QtGui
import datetime
from calendar import monthrange
import pickle
class Event():
«» «Класс события»"»
def __init__(self, evtype, description, y=[], yd=[], m=[], md=[], nwd=[], wd=[], delta=[]):
if delta == []:
delta = [datetime.timedelta()]
if evtype not in ['birthday', # дни рождений (всегда ук. год)
'holiday', # праздники (год указан - ук, когда, не указан - пох)
'event']: # свое событие (полная проверка)
raise Exception ('Неизвестный тип события')
self.type = evtype
self.description = description
self.y = y
self.yd = yd
self.m = m
self.md = md
self.nwd = nwd
self.wd = wd
self.delta = delta
def match (self, date):
«» «Проверяет, попадает ли описание события под дату»"»
if self.y and date.year not in self.y: # если год не совпал
return False
if self.yd and date.timetuple().tm_yday not in self.yd: # день года
return False
if self.m and date.month not in self.m: # месяц
return False
if self.md and date.day not in self.md: # день месяца
return False
if self.wd:
if date.timetuple().tm_wday not in self.wd:
return False
elif self.nwd:
wdn = (((date.timetuple().tm_mday - 1) // 7) + 1)
if wdn not in self.nwd: # n-тый день недели
if 10 in self.nwd: # если условие последний пн..вс в месяце
_, max_mday = monthrange (date.year, date.month)
if (date.timetuple().tm_mday + 7) > max_mday: # проверяем, последний ли это такой день недели в месяце
return True
return False
return True
def get_dates (self, start_date=datetime.date.today() + datetime.timedelta (days=-63), end_date=datetime.date.today() + datetime.timedelta (days=366)):
dates = []
if self.type == 'birthday':
for y in range (start_date.year, end_date.year + 1, 1):
dates.append((datetime.date (y, self.m[0], self.md[0]), ' % s (%d годовщина)'% (self.description, y - self.y[0])))
else:
dinc = datetime.timedelta (days=1)
while start_date <= end_date:
if self.match (start_date):
for d in self.delta:
if self.description == 'holiday' and self.y:
date = (start_date + d, ' % s (%d)'% (self.description, start_date.year - self.y[0]))
else:
date = (start_date + d, self.description)
dates.append(date)
start_date += dinc
return dates
# методы эквивалентности
def __eq__(self, other):
return isinstance (other, self.__class__) and self.__dict__ == other.__dict__
def __ne__(self, other):
return not self.__eq__(other)
def __str__(self):
res = self.description
if self.type == 'birthday':
res += ' (%d.%d.%d)'% (self.md[0], self.m[0], self.y[0])
else:
if self.y:
res += ', г: ' + ' '.join([str(x) for x in self.y])
if self.yd:
res += ', дг: ' + ' '.join([str(x) for x in self.yd])
if self.m:
res += ', м: ' + ' '.join([str(x) for x in self.m])
if self.md:
res += ', дм: ' + ' '.join([str(x) for x in self.md])
if self.wd:
wdn = {0: 'Пн', 1: 'Вт', 2: 'Ср', 3: 'Чт', 4: 'Пт', 5: 'Сб', 6: 'Вс'}
res += ', дн: ' + ' '.join([wdn[x] for x in self.wd])
if self.nwd:
res += ', №дн: ' + ' '.join([str(x) for x in self.nwd])
if self.delta and self.delta[0].days!= 0:
res += ', см: ' + ' '.join([str (x.days) for x in self.delta])
return res
class Calendar (QtGui.QWidget):
«» «Календарь»"»
def __init__(self, parent, data=None):
«» «Инициализация»"»
QtGui.QWidget.__init__(self, parent)
self.name = 'Calendar'
self.wm = parent
# если пришли данные - восстановим
if data:
data = data.split ('\x03')
self.show_notific = eval (data[1])
self.show_tray_notific = eval (data[2])
self.rep_events = pickle.loads (eval(data[3]))
self.single_events = pickle.loads (eval(data[4]))
else:
self.show_notific = True
self.show_tray_notific = True
self.rep_events = []
self.single_events = []
self.grabpoint = None
self.moveing = None
self.minion = False
self.note_wgt = None
self.sin_dates = []
self.rep_dates = []
self.setWindowFlags (QtCore. Qt. Window | QtCore. Qt. FramelessWindowHint)
self.setWindowTitle («Calendar widget»)
self.resize (230, 185)
self.bg = QtGui.QPixmap («widgets/calendar/bg.png»)
pal = self.palette()
pal.setBrush (QtGui.QPalette. Normal, QtGui.QPalette. Window, QtGui.QBrush (self.bg))
pal.setBrush (QtGui.QPalette. Inactive, QtGui.QPalette. Window, QtGui.QBrush (self.bg))
self.setPalette(pal)
self.setMask (self.bg.mask())
self.calendar = QtGui.QCalendarWidget(self)
self.calendar.setVerticalHeaderFormat (QtGui.QCalendarWidget. NoVerticalHeader)
self.calendar.setFirstDayOfWeek (QtCore. Qt. Monday)
self.calendar.move (0, 30)
self.dformat = QtGui.QTextCharFormat()
self.dformat.setFontWeight (QtGui.QFont. Black)
self.dformat.setFontUnderline(True)
ftoday = QtGui.QTextCharFormat()
tbrush = QtGui.QBrush (QtGui.QColor (20, 250, 20, 100))
ftoday.setBackground(tbrush)
self.calendar.setDateTextFormat (datetime.date.today(), ftoday)
self.update_events()
# форма добавление даты
self.add_ev_wgt = QtGui.QWidget()
self.add_ev_wgt.setWindowTitle ('Добавление события')
self.add_ev_wgt.setLayout (QtGui.QVBoxLayout())
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel ('Тип события'))
self.ev_type = QtGui.QComboBox()
self.ev_type.addItem ('День рождения')
self.ev_type.addItem ('Знаменательная дата')
self.ev_type.addItem('Событие')
layout.addWidget (self.ev_type)
self.add_ev_wgt.layout().addLayout(layout)
layout = QtGui.QHBoxLayout()
self.rep_ev = QtGui.QCheckBox()
self.rep_ev.setText ('Повторять событие')
layout.addWidget (self.rep_ev)
hlp_btn = QtGui.QPushButton('Справка')
QtCore.QObject.connect (hlp_btn, QtCore.SIGNAL ('clicked()'), self, QtCore.SLOT ('show_help()'))
layout.addWidget (hlp_btn)
self.add_ev_wgt.layout().addLayout(layout)
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel('Описание'))
layout.addSpacing(37)
self.ev_descr = QtGui.QLineEdit()
layout.addWidget (self.ev_descr)
self.add_ev_wgt.layout().addLayout(layout)
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel('Год'))
layout.addSpacing(68)
self.ev_y = QtGui.QLineEdit()
layout.addWidget (self.ev_y)
self.add_ev_wgt.layout().addLayout(layout)
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel('Месяц'))
layout.addSpacing(56)
self.ev_m = QtGui.QLineEdit()
layout.addWidget (self.ev_m)
self.add_ev_wgt.layout().addLayout(layout)
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel ('День месяца'))
layout.addSpacing(23)
self.ev_md = QtGui.QLineEdit()
layout.addWidget (self.ev_md)
self.add_ev_wgt.layout().addLayout(layout)
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel ('День в году'))
layout.addSpacing(25)
self.ev_yd = QtGui.QLineEdit()
layout.addWidget (self.ev_yd)
self.add_ev_wgt.layout().addLayout(layout)
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel ('День недели'))
self.ev_wd0 = QtGui.QCheckBox()
self.ev_wd0.setText('Пн')
layout.addWidget (self.ev_wd0)
self.ev_wd1 = QtGui.QCheckBox()
self.ev_wd1.setText('Вт')
layout.addWidget (self.ev_wd1)
self.ev_wd2 = QtGui.QCheckBox()
self.ev_wd2.setText('Ср')
layout.addWidget (self.ev_wd2)
self.ev_wd3 = QtGui.QCheckBox()
self.ev_wd3.setText('Чт')
layout.addWidget (self.ev_wd3)
self.ev_wd4 = QtGui.QCheckBox()
self.ev_wd4.setText('Пт')
layout.addWidget (self.ev_wd4)
self.ev_wd5 = QtGui.QCheckBox()
self.ev_wd5.setText('Сб')
layout.addWidget (self.ev_wd5)
self.ev_wd6 = QtGui.QCheckBox()
self.ev_wd6.setText('Вс')
layout.addWidget (self.ev_wd6)
self.add_ev_wgt.layout().addLayout(layout)
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel ('n-ый день недели'))
self.ev_nwd1 = QtGui.QCheckBox()
self.ev_nwd1.setText('1')
layout.addWidget (self.ev_nwd1)
self.ev_nwd2 = QtGui.QCheckBox()
self.ev_nwd2.setText('2')
layout.addWidget (self.ev_nwd2)
self.ev_nwd3 = QtGui.QCheckBox()
self.ev_nwd3.setText('3')
layout.addWidget (self.ev_nwd3)
self.ev_nwd4 = QtGui.QCheckBox()
self.ev_nwd4.setText('4')
layout.addWidget (self.ev_nwd4)
self.ev_nwd5 = QtGui.QCheckBox()
self.ev_nwd5.setText('5')
layout.addWidget (self.ev_nwd5)
self.ev_nwd10 = QtGui.QCheckBox()
self.ev_nwd10.setText('Последний')
layout.addWidget (self.ev_nwd10)
self.add_ev_wgt.layout().addLayout(layout)
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel ('Смещение, дней'))
layout.addSpacing(4)
self.ev_delta = QtGui.QLineEdit()
layout.addWidget (self.ev_delta)
self.add_ev_wgt.layout().addLayout(layout)
add_ev_btn = QtGui.QPushButton ('Добавить событие')
QtCore.QObject.connect (add_ev_btn, QtCore.SIGNAL ('clicked()'), self, QtCore.SLOT ('add_event()'))
self.add_ev_wgt.layout().addWidget (add_ev_btn)
# Список событий и их удаление
self.del_event_wgt = QtGui.QWidget()
self.del_event_wgt.setWindowTitle ('Список событий')
self.del_event_wgt.setLayout (QtGui.QVBoxLayout())
layout = QtGui.QHBoxLayout()
layout.addWidget (QtGui.QLabel ('Повторяемость события'))
self.del_ev_type = QtGui.QComboBox()
self.del_ev_type.addItem('Повторяемое')
self.del_ev_type.addItem('Разовое')
QtCore.QObject.connect (self.del_ev_type, QtCore.SIGNAL («currentIndexChanged(int)»), self.refresh_ev_list)
layout.addWidget (self.del_ev_type)
self.del_event_wgt.layout().addLayout(layout)
self.ev_list = QtGui.QListView()
self.ev_model = QtGui.QStandardItemModel (self.ev_list)
self.ev_list.setModel (self.ev_model)
self.del_event_wgt.layout().addWidget (self.ev_list)
del_ev_btn = QtGui.QPushButton()
del_ev_btn.setText ('Удалить событие')
self.del_event_wgt.layout().addWidget (del_ev_btn)
QtCore.QObject.connect (del_ev_btn, QtCore.SIGNAL («clicked()»), self, QtCore.SLOT ('del_event()'))
#-
self.cb = QtGui.QPushButton(self)
self.cb.resize (20, 20)
self.cb.setIcon (QtGui.QIcon (QtGui.QPixmap («widgets/calendar/cb.png»)))
self.cb.move (205, 5)
self.cfg_b = QtGui.QPushButton(self)
self.cfg_b.resize (20, 20)
self.cfg_b.setIcon (QtGui.QIcon (QtGui.QPixmap («widgets/calendar/cfg_b.png»)))
self.cfg_b.move (185, 5)
self.aeb = QtGui.QPushButton(self)
self.aeb.resize (20, 20)
self.aeb.setIcon (QtGui.QIcon (QtGui.QPixmap («widgets/calendar/aeb.png»)))
self.aeb.move (165, 5)
QtCore.QObject.connect (self.aeb, QtCore.SIGNAL («clicked()»), self, QtCore.SLOT ('create_event()'))
QtCore.QObject.connect (self.cfg_b, QtCore.SIGNAL («clicked()»), self, QtCore.SLOT ('configure()'))
QtCore.QObject.connect (self.cb, QtCore.SIGNAL («clicked()»), self, QtCore.SLOT («exit()»))
QtCore.QObject.connect (self.calendar, QtCore.SIGNAL («clicked(QDate)»), self.date_clicked)
QtCore.QObject.connect (self.calendar, QtCore.SIGNAL («activated(QDate)»), self.on_activate)
self.show()
self.timer_id = self.startTimer(1000)
def timerEvent (self, *args, **kwargs):
self.killTimer (self.timer_id)
self.date_clicked (QtCore.QDate (datetime.date.today()), init_msg=True)
def on_activate (self, date):
date = date.toPyDate()
self.ev_y.setText (str(date.year))
self.ev_m.setText (str(date.month))
self.ev_md.setText (str(date.day))
self.ev_type.setCurrentIndex(2)
self.add_ev_wgt.show()
self.note_wgt.hide()
def update_events(self):
self.calendar.setDateTextFormat (QtCore.QDate(), self.dformat)
ftoday = QtGui.QTextCharFormat()
tbrush = QtGui.QBrush (QtGui.QColor (20, 250, 20, 100))
ftoday.setBackground(tbrush)
self.calendar.setDateTextFormat (datetime.date.today(), ftoday)
self.rep_dates.clear()
for ev in self.rep_events:
self.rep_dates.extend (ev.get_dates())
self.sin_dates.clear()
for ev in self.single_events:
self.sin_dates.extend (ev.get_dates())
for dt in self.rep_dates:
self.calendar.setDateTextFormat (dt[0], self.dformat)
for dt in self.sin_dates:
self.calendar.setDateTextFormat (dt[0], self.dformat)
@QtCore.pyqtSlot()
def create_event(self):
«» «Слот при нажатии на 'Добавить событие'»"»
self.add_ev_wgt.show()
@QtCore.pyqtSlot()
def add_event(self):
«» «Слот при нажатии на 'Добавить событие'»"»
all_ok = True
err_txt = ''
try:
y = [int(i) for i in filter (len, self.ev_y.text().replace (' ', ', ').split (', '))]
m = [int(i) for i in filter (len, self.ev_m.text().replace (' ', ', ').split (', '))]
md = [int(i) for i in filter (len, self.ev_md.text().replace (' ', ', ').split (', '))]
descr = self.ev_descr.text()
if len(descr) < 3:
all_ok = False
err_txt = 'Описание должно быть больше 4 символов\n'
if self.ev_type.currentText() == 'День рождения':
if len(y) == 1 and len(m) == 1 and len(md) == 1:
ev = Event (evtype='birthday', y=y, m=m, md=md, description=descr)
else:
err_txt = 'Для дня рождения только год, месяц и день\n'
all_ok = False
else:
yd = [int(i) for i in filter (len, self.ev_yd.text().replace (' ', ', ').split (', '))]
wd = []
if self.ev_wd0.isChecked():
wd.append(0)
if self.ev_wd1.isChecked():
wd.append(1)
if self.ev_wd2.isChecked():
wd.append(2)
if self.ev_wd3.isChecked():
wd.append(3)
if self.ev_wd4.isChecked():
wd.append(4)
if self.ev_wd5.isChecked():
wd.append(5)
if self.ev_wd6.isChecked():
wd.append(6)
nwd = []
if self.ev_nwd1.isChecked():
nwd.append(1)
if self.ev_nwd2.isChecked():
nwd.append(2)
if self.ev_nwd3.isChecked():
nwd.append(3)
if self.ev_nwd4.isChecked():
nwd.append(4)
if self.ev_nwd5.isChecked():
nwd.append(5)
if self.ev_nwd10.isChecked():
nwd.append(10)
delta = [datetime.timedelta (days=int(i)) for i in filter (len, self.ev_delta.text().replace (' ', ', ').split (', '))]
evtype = 'event' if self.ev_type.currentText() == «Событие» else 'holiday'
if len(y) < 1 and len(yd) < 1 and len(m) < 1 and len(md) < 1 and len(nwd) < 1 and len(wd) < 1 and len(delta) < 1:
all_ok = False
err_txt = 'Поля пусты!\n'
if evtype == 'event' and not self.rep_ev.isChecked():
if len(y)!= 1 or len(yd) > 1 or len(m) > 1 or len(md) > 1 or len(nwd) > 1 or len(wd) > 1 or len(delta) > 1:
all_ok = False
err_txt = 'Для неповторяемых событий нельзя\nзадавать больше одного значения в критерии\nГод должен быть задан\n (например, несколько чисел месяца)\n'
ev = Event (evtype=evtype, description=descr, y=y, yd=yd, m=m, md=md, nwd=nwd, wd=wd, delta=delta)
except:
all_ok = False
if all_ok:
if not self.rep_ev.isChecked() and ev.type == 'event':
self.single_events.append(ev)
else:
self.rep_events.append(ev)
self.add_ev_wgt.hide()
self.update_events()
self.wm.trayMessage ('Событие добавлено', 'Событие «%s» добавлено!'% self.ev_descr.text())
else:
msg = QtGui.QMessageBox (self.add_ev_wgt)
msg.setWindowTitle('Ошибка')
msg.setText ('Поля заполнены неверно\n % sОбратитесь к справке'% err_txt)
msg.show()
@QtCore.pyqtSlot()
def del_event(self):
«» «Слот при нажатии на 'Удалить событие'»"»
sel = self.ev_list.selectedIndexes()
if len(sel) == 1:
ev_str = sel[0].data()
for i in range (len(self.ev_l_storage)):
if str (self.ev_l_storage[i]) == ev_str:
self.ev_l_storage.pop(i)
break
self.refresh_ev_list()
self.update_events()
@QtCore.pyqtSlot()
def show_help(self):
«» «Слот при нажатии 'Справка'»"»
msg = QtGui.QMessageBox (self.add_ev_wgt)
msg.setWindowTitle ('Справка по добавлению события')
help_text = «"»
Сперва выберите тип события:
День рождения - чей-либо День рождения. В заметке календаря, помимо описания и даты будет указано количество лет, которое исполняется имениннику.
Знаменательная дата - памятная дата. Какой-либо праздник, день траура или просто приметное событие. В заметке календаря, помимо описания и даты будет указано количество лет, прошедшее с года наступления, если указан год.
Событие - просто событие, или напоминание. В заметке календаря будет указана только дата и описание. События могут быть разовыми, а могут и повторяться (галочка «повторять событие»). Если событие одноразовое, для него нельзя указать несколько критериев одного типа, например, указать дни месяца «14, 17» или отметить галочкой «Пн» и «Вт»
Затем, необходимо заполнить критерии, по которым эти события наступят. В полях критериев пишутся целые цисла. Можно указывать несколько значений через зяпятую или через пробел (например, указав «1, 12» месяц и поставив галочку на «Пн», событие будет наступать каждый понедельник Января и Декабря каждого года).
Если критерий не указан, то этот критерий считается неважным (например, если год не указан, то событие будет проверяться каждый год; если указан только 1 день месяца, то событие будет наступать каждый этот день месяца каждого года).
Событие наступит только если все указанные критерии совпали.
Для Дня рождения нужно указать год, месяц(число) и день. Другие критерии игнорируются.
Для Знаменательной даты можно указывать любые критерии.
Для События можно указывать любые критерии. Только это событие может быть разовым.
Особый критерий - Смещение. Может быть положительным или отрицательным. Он указывает сдвиг в днях относительно критериев. Он помогает при праздновании переходящих праздников.
Если нужно указать каждый последний день месяца, то лучше всего указать день месяца «1» и смещение -1. Таким образом, событие будет наступать последний день каждого месяца.
День в году указывает номер дня в году. Например, День программиста наступает каждый 256 день в году.
«»»
msg.setText (help_text)
msg.show()
@QtCore.pyqtSlot()
def exit(self):
«» «Слот при нажатии кнопки закрытия»"»
self.wm.widget_list.remove(self)
self.hide()
self.destroy()
def near_events_text(self):
dnow = datetime.date.today()
edate = dnow + datetime.timedelta (days=30)
today = []
near_events = []
for d in self.rep_dates:
if d[0] == dnow:
today.append(d)
if dnow < d[0] <= edate:
near_events.append(d)
for d in self.sin_dates:
if d[0] == dnow:
today.append(d)
if dnow < d[0] <= edate:
near_events.append(d)
res = 'В ближайшие 30 дней событий нет'
if today:
res = 'Сегодня\n' + '\n'.join([d[1] for d in today])
if near_events:
res = 'Через:\n'
for d in near_events:
res += ' % d дней % s\n'% ((d[0] - dnow).days, d[1])
return res
def date_clicked (self, date, init_msg=False):
«» «Кликнули на дате»"»
dnow = date.toPyDate()
text = 'Заметка календаря\n % s\n'% str(dnow)
dates = []
if init_msg:
text = 'Заметка календаря\n % s\n'% self.near_events_text()
else:
for d in self.rep_dates:
if d[0] == dnow:
dates.append(d)
for d in self.sin_dates:
if d[0] == dnow:
dates.append(d)
if dates or init_msg:
text += '\n'.join([d[1] for d in dates])
if self.note_wgt is None or self.note_wgt.isHidden():
self.note_wgt = self.wm.addWidget('Note')
self.note_wgt.minion = True
self.note_wgt.tf.setReadOnly(True)
self.note_wgt.move (self.x() + (self.width() - self.note_wgt.width()) // 2, self.y() + self.height())
self.note_wgt.set_text(text)
else:
if self.note_wgt:
self.note_wgt.hide()
@QtCore.pyqtSlot()
def configure(self):
«» «Кнопка конфигурации»"»
self.refresh_ev_list()
self.del_event_wgt.show()
def refresh_ev_list(self):
self.ev_model.clear()
self.ev_l_storage = self.single_events if self.del_ev_type.currentText() == «Разовое» else self.rep_events
for ev in self.ev_l_storage:
item = QtGui.QStandardItem (str(ev))
self.ev_model.appendRow(item)
# следующие 2 метода задают поведение: виджет будет перетаскиваться при перетаскивании мыши
def mousePressEvent (self, event):
«» «Записывает координаты нажатия мыши»"»
if event.button() == QtCore. Qt. LeftButton:
self.grabpoint = event.pos()
self.moveing = True
# up
def mouseMoveEvent (self, event):
«» «Перетаскивает виджет за курсором мыши»"»
if (event.buttons() & QtCore. Qt. LeftButton) and self.moveing:
newx = self.x() + event.pos().x() - self.grabpoint.x()
newy = self.y() + event.pos().y() - self.grabpoint.y()
if 0 <= newx <= (self.wm.max_size.width() - self.width()):
self.move (newx, self.y())
if 0 <= newy <= (self.wm.max_size.height() - self.height()):
self.move (self.x(), newy)
def serialize(self):
«»«Сериализация. Ввиду того, что это PyQt,
стандартные методы не подходят
(c object'ты не сериализуются)""»
return '\x03'.join([self.name,
repr (self.show_notific),
repr (self.show_tray_notific),
repr (pickle.dumps (self.rep_events)),
repr (pickle.dumps (self.single_events))])
widgets/note/__init__.py
«»»
Виджет заметок
«»»
from PyQt4 import QtCore, QtGui
class Note (QtGui.QWidget):
«» «Заметка»"»
def __init__(self, parent, data=None):
«» «Инициализация»"»
QtGui.QWidget.__init__(self, parent)
self.name = 'Note'
self.wm = parent
# если пришли данные - восстановим
if data:
data = data.split ('\x03')
self.tf = QtGui.QTextEdit (eval(data[1]), self)
else:
self.tf = QtGui.QTextEdit(self)
self.grabpoint = None
self.moveing = None
self.minion = False # если True, то cwm не будет его сериализовывать
self.setWindowFlags (QtCore. Qt. Window | QtCore. Qt. FramelessWindowHint)
self.setWindowTitle («Note widget»)
self.resize (220, 220)
self.bg = QtGui.QPixmap («widgets/note/bg.png»)
pal = self.palette()
pal.setBrush (QtGui.QPalette. Normal, QtGui.QPalette. Window, QtGui.QBrush (self.bg))
pal.setBrush (QtGui.QPalette. Inactive, QtGui.QPalette. Window, QtGui.QBrush (self.bg))
self.setPalette(pal)
self.setMask (self.bg.mask())
self.cb = QtGui.QPushButton(self)
self.cb.resize (20, 20)
self.cb.setIcon (QtGui.QIcon (QtGui.QPixmap («widgets/note/cb.png»)))
self.cb.move (195, 5)
self.clrb = QtGui.QPushButton(self)
self.clrb.resize (20, 20)
self.clrb.setIcon (QtGui.QIcon (QtGui.QPixmap («widgets/note/clrb.png»)))
self.clrb.move (175, 5)
self.tf.move (-1, 30)
self.tf.resize (222, 191)
p = self.tf.palette()
p.setColor (QtGui.QPalette. Base, QtGui.QColor (0xf7, 0xf5, 0xb5, 255))
self.tf.setPalette(p)
QtCore.QObject.connect (self.clrb, QtCore.SIGNAL («clicked()»), self, QtCore.SLOT ('clear_note()'))
QtCore.QObject.connect (self.cb, QtCore.SIGNAL («clicked()»), self, QtCore.SLOT («exit()»))
self.show()
@QtCore.pyqtSlot()
def clear_note(self):
«» «Слот при нажатии стерки. Удаляет текст заметки»"»
self.tf.setText('')
@QtCore.pyqtSlot()
def exit(self):
«» «Слот при нажатии кнопки закрытия»"»
self.wm.widget_list.remove(self)
self.hide()
self.destroy()
def set_text (self, text):
«» «Метод для задания текста путем внешнего вызова»"»
self.tf.setText(text)
self.update()
# следующие 2 метода задают поведение: виджет будет перетаскиваться при перетаскивании мыши
def mousePressEvent (self, event):
«» «Записывает координаты нажатия мыши»"»
if event.button() == QtCore. Qt. LeftButton:
self.grabpoint = event.pos()
self.moveing = True
# up
def mouseMoveEvent (self, event):
«» «Перетаскивает виджет за курсором мыши»"»
if (event.buttons() & QtCore. Qt. LeftButton) and self.moveing:
newx = self.x() + event.pos().x() - self.grabpoint.x()
newy = self.y() + event.pos().y() - self.grabpoint.y()
if 0 <= newx <= (self.wm.max_size.width() - self.width()):
self.move (newx, self.y())
if 0 <= newy <= (self.wm.max_size.height() - self.height()):
self.move (self.x(), newy)
def serialize(self):
«»«Сериализация. Ввиду того, что это PyQt,
стандартные методы не подходят
(c object'ты не сериализуются)""»
return '\x03'.join([self.name,
repr (self.tf.toPlainText())])
server.py
import socket
import os
def mainloop():
sock = socket.socket()
sock.bind(('', 33333))
sock.listen(1)
print('started')
while True:
ans = ''
conn, addr = sock.accept()
print ('connected to ' + str(addr))
data = conn.recv(1024)
if data:
print ('recieved from ' + str(addr) + ': ' + str(data))
code, login, password, data = data.split (' ', 3)
if code == 'L':
try:
with open ('userdata/%s/pass'% str(login)) as lg:
if password.strip()!= lg.read().strip():
ans = 'W'
else:
ans = 'Y ' + open ('userdata/%s/data'% str(login)).read()
except IOError:
ans = 'E'
elif code == 'S':
try:
with open ('userdata/%s/pass'% str(login)) as lg:
if password.strip()!= lg.read().strip():
ans = 'W'
else:
open ('userdata/%s/data'% str(login), 'w').write(data)
except IOError:
# такого юзера еще нет, создаем
if not os.path.exists ('userdata/%s'% str(login)):
os.mkdir ('userdata/%s'% str(login))
open ('userdata/%s/pass'% str(login), 'w').write(password)
open ('userdata/%s/data'% str(login), 'w').write(data)
ans = 'Y'
else:
ans = 'N'
else:
ans = 'N'
conn.send(ans)
conn.close()
print ('disconnected from ' + str(addr))
if __name__ == '__main__':
try:
if not os.path.exists('userdata'):
os.mkdir('userdata')
mainloop()
except Exception as e:
print(e)
Размещено на Allbest.ru
Подобные документы
Программа смены обоев рабочего стола, принцип ее работы. Основные виды обоев для рабочего стола. Существующие программы и их преимущества. Разработка приложения для смены обоев рабочего стола с использованием функций программы Delphi 7, листинг программы.
контрольная работа [3,8 M], добавлен 17.11.2012Аппаратные и программные средства для разработки веб-сайта. Ознакомление с характеристиками мобильных устройств фирмы Nexus. Установка логотипа сайта. Создание главной страницы. Активация слайдера и панели виджетов. Конфигурирование настроек слайдера.
дипломная работа [11,2 M], добавлен 10.10.2016Элементы рабочего стола. Общие приемы работы с окнами. Главное и контекстное меню. Создание и переименование папок. Удаление и восстановление информации. Копирование информации на съемные носители. Настройка Рабочего стола. Настройка панели задач.
учебное пособие [346,4 K], добавлен 20.08.2010Анализ видов существующих корпоративных порталов. Разработка архитектуры и структуры корпоративного портала в соответствии с требованиями. Установка и настройка программного обеспечения. Общие настройки портала, управление меню и настройка виджетов.
дипломная работа [4,8 M], добавлен 19.01.2017Реализация шаблона проектирования c основными принципами GUI. Обзор простых Swing-виджетов. Первая программа и добавление кнопки. Диспетчер компоновки Layout Manager. Установка размера компонента. Создание объекта Swinq в потоке обработки событий и меню.
презентация [491,3 K], добавлен 26.10.2013Проектирование структур данных и пользовательского интерфейса. Разработка руководства системного программиста и пользователя. Основные элементы организации работы менеджера по работе с клиентами. Характеристика программного обеспечения ООО "Доминион+".
курсовая работа [1,7 M], добавлен 14.10.2012Стандартные компоненты Windows XP. Главное меню, панель задач, оформление рабочего стола и значки рабочего стола. Требования к минимальной конфигурации, необходимой для установки Windows XP на платформе Intel. Удаленный доступ к рабочему столу.
курсовая работа [1,1 M], добавлен 14.01.2015D-Series как система автоматизации телевещательного процесса, используемая современными телестудиями. Портирование компонентов системы для работы на операционных системах Windows. Проверка корректного подключения плагинов и ручного режима воспроизведения.
дипломная работа [2,3 M], добавлен 21.09.2016Разработка и реализация автоматизированного рабочего места для менеджера по продажам компьютерной техники. Требования к функциональным характеристика программного изделия. Стадии и этапы разработки. Эксплуатационная документация, руководство оператора.
курсовая работа [686,9 K], добавлен 19.05.2014Определение общих требований к организации автоматизированного рабочего места. Создание модели автоматизированного рабочего места менеджера фирмы "Информстиль". Разработка базы данных и описание алгоритма программы по учету продаж вычислительной техники.
дипломная работа [2,9 M], добавлен 03.07.2015