def createDate(self, popup: QDialog, hours: int, minutes: int, seconds: int): popup.close() self.begin_time = datetime.timestamp(datetime.now()) now = datetime.now().time() target = time(hours, minutes, seconds) now_delta = timedelta(hours=now.hour, minutes=now.minute, seconds=now.second) target_delta = timedelta(hours=target.hour, minutes=target.minute, seconds=target.second) if target_delta == now_delta: self.end_time = self.begin_time + 60 * 60 * 24 else: d = target_delta - now_delta self.end_time = self.begin_time + d.seconds self.progressBar.setRange(0, 100) self.progressBar.setValue(0) self.isRunning = True self.timer.stop() self.timer.start(self.refresh_rate)
def createDuration(self, popup: QDialog, hours: int, minutes: int, seconds: int): popup.close() self.begin_time = datetime.timestamp(datetime.now()) self.end_time = self.begin_time + seconds + minutes * 60 + hours * 3600 self.progressBar.setRange(0, 100) self.progressBar.setValue(0) self.isRunning = True self.timer.stop() self.timer.start(self.refresh_rate)
def __disable(self): """Restores the ownership of the inner widget to its GraphicsNode.""" self.setWidget(None) self.__inner_widget.setParent(None) dialog = QDialog() layout = QVBoxLayout() layout.addWidget(self.__inner_widget) dialog.setLayout(layout) dialog.show() self.__inner_widget.setParent(None) self.__inner_widget.resize(self.__last_size) self.__graphics_node.set_inner_widget(self.__inner_widget) dialog.close()
def __init__(self, message, title=bdstr.information): """Class constructor. Parameters: message: the question to be displayed title: the window title """ QDialog.__init__(self) self.setWindowTitle(title) self.gridlayout = QGridLayout() self.textarea = QTextEdit(message) self.textarea.setReadOnly(True) self.gridlayout.addWidget(self.textarea, 0, 0, 1, 2) self.okbutton = QPushButton(bastr.ok, self) self.okbutton.clicked.connect(lambda: QDialog.close(self)) self.gridlayout.addWidget(self.okbutton, 1, 1) self.setLayout(self.gridlayout) self.setGeometry(100, 100, 600, 400) qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) self.exec_()
class Plotter(FigureCanvasQTAgg): def __init__(self, xtitle=None, ytitle=None, width=5, height=4, dpi=100): fig = Figure(figsize=(width, height), dpi=dpi) self.axes = fig.add_subplot(111) self.axes.autoscale(enable=True) super().__init__(fig) self._createDialog() self._needsUpdating = False self.updateTimer = QTimer() self.updateTimer.setSingleShot(False) self.updateTimer.setInterval(UPDATE_INTERVAL) self.updateTimer.timeout.connect(self._updateFigure) self.updateThread = QThread() self.updateThread.started.connect(self._refreshFigure) self.xdata = list(range(MAXIMUM_POINTS)) self.ydata = [0] * MAXIMUM_POINTS #The following lines may not be correct self.xtitle = xtitle self.ytitle = ytitle self.xtitle("SAMPLE X") # self._plot_ref = None self._showDialog() self.updateTimer.start() def _updateFigure(self): if self._needsUpdating: self.updateThread.start() def _refreshFigure(self): # if self._plot_ref is None: # self._plot_ref, = self.axes.plot(self.xdata, self.ydata, 'r', marker='o', markersize=12) # else: # self._plot_ref.set_xdata(self.xdata) # self._plot_ref.set_ydata(self.ydata) self.axes.cla() self.axes.plot(self.xdata, self.ydata, 'r', marker='o', markersize=12) if self.xtitle is not None: self.axes.xtitle(self.xtitle) if self.ytitle is not None: self.axes.ytitle(self.ytitle) self.draw() self._needsUpdating = False def _createDialog(self): self.plotDialog = QDialog() self.plotDialog.setWindowTitle("Processing Plot") dialogButtons = QDialogButtonBox(QDialogButtonBox.Close) dialogButtons.clicked.connect(self._closeDialog) layout = QVBoxLayout() self.toolbar = NavigationToolbar(self, self.plotDialog) layout.addWidget(self.toolbar) layout.addWidget(self) layout.addWidget(dialogButtons) self.plotDialog.setLayout(layout) def _closeDialog(self): self.plotDialog.close() def _showDialog(self): self.plotDialog.show() def addNewData(self, x, y): #Check data validity x = np.array(x).flatten() y = np.array(y).flatten() if x.size != y.size: print( "Problem with adding new values to the plot, x and y should have the same length" ) return #TODO: Add other validation conditions #Add data to class length = x.shape[0] self.xdata = self.xdata[-(MAXIMUM_POINTS - length):] + x.tolist() self.ydata = self.ydata[-(MAXIMUM_POINTS - length):] + y.tolist() #flag it for updates self._needsUpdating = True def __del__(self): self.plotDialog.close() while not self.updateThread.isFinished(): pass
class SupportDialog(QObject): SHORT_FEEDBACK_INTERVAL = 5 * 60 * 1000 DAYS_TO_FEEDBACK = 7 DROPDOWN_BACKGROUND_COLOR = "#f78d1e" DROPDOWN_COLOR = "white" _sending_error = Signal() SUBJECT = { 1: "TECHNICAL", 2: "OTHER", 3: "FEEDBACK", } def __init__(self, parent, parent_window, config, dp=1, selected_index=0): QObject.__init__(self, parent) self._parent = parent self._parent_window = parent_window self._config = config self._dp = dp self._selected_index = selected_index self._dialog = QDialog(parent_window) self._dialog.setWindowFlags(Qt.Dialog) self._dialog.setAttribute(Qt.WA_MacFrameworkScaled) self._is_opened = False self._pipe = None self._feedback_mode = False self._ui = Ui_Dialog() self._ui.setupUi(self._dialog) self._init_ui() self._old_close_event = self._dialog.closeEvent self._feedback_timer = QTimer(self) self._feedback_timer.setSingleShot(True) self._feedback_timer.timeout.connect(self._show_feedback_form) self._parent.service_started.connect(self._check_feedback_needed) self._parent.exit_request.connect(self._on_exit_request) def _init_ui(self): self._ui.pushButton.setEnabled(False) self._ui.comboBox.addItem(tr("---Select Subject---")) self._ui.comboBox.addItem(tr("Technical Question")) self._ui.comboBox.addItem(tr("Other Question")) self._ui.comboBox.addItem(tr("Feedback")) self._ui.comboBox.setCurrentIndex(self._selected_index) palette = self._ui.comboBox.palette() palette.setColor(QPalette.HighlightedText, QColor(self.DROPDOWN_COLOR)) palette.setColor(QPalette.Highlight, QColor(self.DROPDOWN_BACKGROUND_COLOR)) self._ui.comboBox.setPalette(palette) palette = self._ui.comboBox.view().palette() palette.setColor(QPalette.HighlightedText, QColor(self.DROPDOWN_COLOR)) palette.setColor(QPalette.Highlight, QColor(self.DROPDOWN_BACKGROUND_COLOR)) self._ui.comboBox.view().setPalette(palette) self._set_tooltip() self._ui.comboBox.currentIndexChanged.connect(self._on_index_changed) self._ui.plainTextEdit.textChanged.connect(self._set_tooltip) self._ui.pushButton.clicked.connect(self._on_send_clicked) self._ui.text_label.linkActivated.connect(self._on_link_activated) self._sending_error.connect(self._clear_pipe_state) self._set_fonts() def _set_fonts(self): ui = self._ui controls = [ ui.plainTextEdit, ui.pushButton, ui.comboBox, ui.text_label, ui.checkBox ] for control in controls: font = control.font() font_size = control.font().pointSize() * self._dp if font_size > 0: control_font = QFont(font.family(), font_size) control_font.setBold(font.bold()) control.setFont(control_font) def set_selected_index(self, selected_index): self._selected_index = selected_index if self._is_opened: self._ui.comboBox.setCurrentIndex(self._selected_index) def show(self): if self._parent.dialogs_opened(): return self._is_opened = True logger.debug("Support dialog opening...") self._pipe = None self.set_selected_index(self._selected_index) self._ui.checkBox.setChecked(False) self._ui.comboBox.setEnabled(not self._feedback_mode) self._dialog.exec_() logger.debug("Support dialog closed") if self._pipe: try: self._pipe.stop() self._clear_pipe_state() except Exception as e: logger.error("Unexpected error stopping pipe: (%s)", e) self._is_opened = False self._selected_index = 0 self._ui.plainTextEdit.document().clear() self._ui.checkBox.setChecked(False) def dialog_opened(self): return self._is_opened def close(self): self._dialog.close() def _set_tooltip(self): if not self._selected_index: tooltip = tr("Please select subject") self._ui.pushButton.setEnabled(False) elif not self._ui.plainTextEdit.document().toPlainText(): tooltip = tr("Message can't be empty") self._ui.pushButton.setEnabled(False) else: tooltip = tr("Click to send message") self._ui.pushButton.setEnabled(True) self._ui.pushButton.setToolTip(tooltip) def _on_index_changed(self, selected_index): self._selected_index = selected_index self._set_tooltip() def _on_send_clicked(self): self._dialog.setEnabled(False) self._pipe = ProgressPipe(self, self._ui.pushButton, timeout=1000, final_text=tr("Sent"), final_timeout=500) self._pipe.pipe_finished.connect(self._on_pipe_finished) if self._ui.checkBox.isChecked(): self._pipe.add_task(tr("Compressing"), self._archive_logs()) self._pipe.add_task(tr("Uploading"), self._upload_file()) self._pipe.add_task(tr("Sending"), self._send_message()) self._pipe.start() def _on_pipe_finished(self): self._clear_feedback_flag() self.close() def _clear_pipe_state(self): self._dialog.setEnabled(True) try: self._pipe.pipe_finished.disconnect(self._on_pipe_finished) except Exception as e: logger.warning("Can't disconnect signal: %s", e) self._ui.pushButton.setText(tr("SEND")) def _send_message(self): def send(log_file_name=""): logger.debug("Support compressed log_file_name %s", log_file_name) if self._selected_index not in self.SUBJECT: logger.warning("Attempt to send message to support " "with invalid subject") return subject = self.SUBJECT[self._selected_index] res = self._parent.web_api.send_support_message( subject, self._ui.plainTextEdit.document().toPlainText(), log_file_name) was_error = False msg = tr("Can't send message to support") if res and "result" in res: if res["result"] != "success": was_error = True msg = str(res.get("info", msg)) else: was_error = True if was_error: self._parent.show_tray_notification(msg) self._sending_error.emit() raise SendingError(msg) return send def _archive_logs(self): def archive(): # uses function attributes to track progress # archive.size, archive.progress, archive.stop logs_dir = get_bases_dir(self._config.sync_directory) log_files = glob("{}{}*.log".format(logs_dir, os.sep)) log_sizes = list(map(os.path.getsize, log_files)) # mark overall size archive.size = sum(log_sizes) old_archives = glob("{}{}2*_logs.zip".format(logs_dir, os.sep)) try: list(map(remove_file, old_archives)) except Exception as e: logger.warning("Can't delete old archives. Reason: (%s)", e) if get_free_space(logs_dir) < archive.size // 5: # archive.size // 5 is approx future archive size msg = tr("Insufficient disk space to archive logs. " "Please clean disk") self._parent.show_tray_notification(msg) self._sending_error.emit() raise SendingError(msg) archive_name = time.strftime('%Y%m%d_%H%M%S_logs.zip') archive_path = "{}{}{}".format(logs_dir, os.sep, archive_name) archive_dir = op.dirname(archive_path) f = zipfile.ZipFile(archive_path, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) try: with cwd(archive_dir): for i, log_file in enumerate(log_files): if not op.isfile(log_file): continue f.write(op.basename(log_file)) # mark progress archive.progress += log_sizes[i] if archive.stop: return except Exception as e: msg = tr("Can't archive logs.") logger.warning(msg + " Reason: (%s)", e) self._parent.show_tray_notification(msg) self._sending_error.emit() raise SendingError(msg) finally: f.close() if archive.stop: remove_file(archive_path) return archive_path return archive def _upload_file(self): def upload(path): # uses function attributes to track progress # upload.size, upload.progress, upload.stop upload.size = op.getsize(path) res = self._parent.web_api.upload_file(path, "application/zip", callback) was_error = False msg = tr("Can't upload archive file") if res and "result" in res: if res["result"] == "success": filename = res.get("file_name", "") else: was_error = True msg = str(res.get("info", msg)) else: was_error = True if was_error and not upload.stop: self._parent.show_tray_notification(msg) self._sending_error.emit() raise SendingError(msg) remove_file(path) return filename def callback(monitor): upload.progress = monitor.bytes_read if upload.stop: raise SendingError("Stopped") return upload def _on_link_activated(self): open_link(self._parent.get_help_uri())() self.close() def _check_feedback_needed(self): if self._feedback_timer.isActive(): return start_date = get_init_done() now = datetime.datetime.now() logger.debug("Start date is %s", start_date) if start_date is None: return interval = (start_date - now) \ + datetime.timedelta(days=self.DAYS_TO_FEEDBACK) if interval.total_seconds() <= 0: logger.debug("Feedback form date time is now") self._show_feedback_form() else: self._feedback_timer.setInterval(interval.seconds * 1000) self._feedback_timer.start() logger.debug("Feedback form date time is %s", now + interval) def _show_feedback_form(self): if self._is_opened: self._feedback_timer.setInterval(self.SHORT_FEEDBACK_INTERVAL) self._feedback_timer.start() return self._feedback_mode = True self._selected_index = 3 self._dialog.closeEvent = self._close_event window_title = self._dialog.windowTitle() label_text = self._ui.text_label.text() feedback_text = tr("Please leave your feedback for Pvtbox") self._ui.text_label.setText( "<html><head/><body><p>{}</p></body></html>".format(feedback_text)) self._dialog.setWindowTitle(tr("Feedback")) self.show() self._dialog.setWindowTitle(window_title) self._ui.text_label.setText(label_text) def _close_event(self, event): if event.spontaneous(): self._clear_feedback_flag() self._old_close_event(event) def _clear_feedback_flag(self): if self._feedback_mode: logger.debug("Feedback flag cleared") clear_init_done() self._feedback_mode = False self._dialog.closeEvent = self._old_close_event def _on_exit_request(self): if self._is_opened: self.close()
class TutorialDialog(object): def __init__(self, parent, dp=None): self._dialog = QDialog(parent) self._dp = dp self._dialog.setWindowIcon(QIcon(':/images/icon.png')) self._ui = Ui_Dialog() self._ui.setupUi(self._dialog) self._current_index = 0 self._ui.slides.setCurrentIndex(self._current_index) self._slides_count = self._ui.slides.count() self._ui.next_button.clicked.connect(self._on_next_button_clicked) self._ui.prev_button.clicked.connect(self._on_prev_button_clicked) self._point_enabled_style = "background-color:#f9af61; " \ "border: 2px solid; " \ "border-radius: 3px; " \ "border-color:#f9af61;" self._point_disabled_style = "background-color:#cccccc; " \ "border: 2px solid; " \ "border-radius: 3px; " \ "border-color:#cccccc;" self._points = [self._ui.point] self._init_points() self._setup_buttons() self._set_labels_fonts() self._set_controls_font([self._ui.next_button, self._ui.prev_button]) self._slide_show = SlideShow(self._dialog, self._ui.slides) self._slide_show.current_index_changed.connect( self._on_current_index_changed) self._slide_show.clicked.connect(self._on_next_button_clicked) self._slide_show.key_pressed.connect(self._on_key_pressed) self._dialog.keyPressEvent = self._on_key_pressed def _on_next_button_clicked(self): if self._current_index + 1 >= self._slides_count: self._close() return self._slide_show.setCurrentIndex(self._current_index + 1) def _on_prev_button_clicked(self): if self._current_index - 1 < 0: return self._slide_show.setCurrentIndex(self._current_index - 1) def _on_key_pressed(self, ev): if ev.key() == Qt.Key_Left: self._on_prev_button_clicked() elif ev.key() == Qt.Key_Right: self._on_next_button_clicked() def _on_current_index_changed(self, new_index): self._current_index = new_index self._setup_buttons() def _setup_buttons(self): if self._current_index == 0: self._ui.prev_button.setDisabled(True) self._ui.prev_button.setStyleSheet( "border: 0; color:#ffffff; text-align:left;") else: self._ui.prev_button.setDisabled(False) self._ui.prev_button.setStyleSheet( "border: 0; color:#222222; text-align:left;") if self._current_index + 1 == self._slides_count: self._ui.next_button.setText(tr("GOT IT")) else: self._ui.next_button.setText(tr("NEXT")) self._setup_points() def _init_points(self): self._points[0].setText(' ') self._points[0].setFont(QFont("Noto Sans", 2)) for i in range(1, self._slides_count): new_point = QLabel() new_point.setText(' ') new_point.setFont(QFont("Noto Sans", 2)) new_point.setStyleSheet(self._point_disabled_style) self._points.append(new_point) self._ui.points_layout.addSpacing(8) self._ui.points_layout.addWidget(new_point) def _setup_points(self): for i, point in enumerate(self._points): style = self._point_enabled_style if i == self._current_index \ else self._point_disabled_style point.setStyleSheet(style) def _set_labels_fonts(self): self._set_controls_font(self._ui.slides.findChildren(QLabel)) def _set_controls_font(self, controls): if not self._dp or self._dp == 1: return for control in controls: font = control.font() font_size = font.pointSize() * self._dp control_font = QFont(font.family(), font_size, italic=font.italic()) control_font.setBold(font.bold()) control.setFont(control_font) def _close(self): self._slide_show.current_index_changed.disconnect( self._on_current_index_changed) self._dialog.accept() self._dialog.close() def show(self): logger.debug("Opening tutorial dialog") # Execute dialog self._dialog.exec_()
class MainWindow(QDialog, Ui_Form_name, Ui_message_box): def __init__(self): super().__init__() self.windows = Ui_Form_name() self.windows.setupUi(self) self.windows.toolButton.clicked.connect(self.file_opener) self.windows.toolButton_2.clicked.connect(self.file_destination) self.windows.pushButton.clicked.connect(self.converter) self.setWindowIcon(QIcon("icons/image.ico")) def file_opener(self): global file_name file_name = QFileDialog.getOpenFileName(None,"Open File", "c:\\users\\{}\\desktop".format(getpass.getuser()),"PDF files(*.pdf)") self.windows.lineEdit_4.setText(file_name[0].split("/")[-1]) def file_destination(self): global file_destination file_destination = QFileDialog.getExistingDirectory(None,"Destination", "c:\\users\\{}\\desktop".format(getpass.getuser())) self.windows.lineEdit_5.setText(file_destination.split('/')[-1]) def converter(self): if self.windows.lineEdit.text() and self.windows.lineEdit_5.text() and self.windows.lineEdit_4.text(): try: date_extracted = tabula.read_pdf("{}".format(file_name[0]), pages='{}'.format(self.windows.lineEdit.text()), lattice=True) data_frame = DataFrame(date_extracted) data_frame.to_excel("{}/{}.xlsx".format(file_destination,file_name[0].split("/")[-1])) self.window2 = QDialog() self.message_box = Ui_message_box() self.message_box.setupUi(self.window2) self.window2.setWindowModality(QtCore.Qt.ApplicationModal) self.window2.show() self.window2.setWindowIcon(QIcon("icons/image.ico")) self.message_box.pushButton.clicked.connect(self.close_message) except Exception as e: print(e) self.window4 = QDialog() self.message_box3 = Ui_error_message() self.message_box3.setupUi(self.window4) self.window4.setWindowModality(QtCore.Qt.ApplicationModal) self.window4.show() self.window4.setWindowIcon(QIcon("image.ico")) self.message_box3.pushButton.clicked.connect(self.error_warning) else: self.window3 = QDialog() self.message_box2 = Ui_invalid_message() self.message_box2.setupUi(self.window3) self.window3.setWindowModality(QtCore.Qt.ApplicationModal) self.window3.show() self.window3.setWindowIcon(QIcon("icons/image.ico")) self.message_box2.pushButton.clicked.connect(self.invalid_warning) def close_message(self): webbrowser.open("{}".format(file_destination)) self.window2.close() def invalid_warning(self): self.window3.close() def error_warning(self): self.window4.close()
def onClose(self): """Close dialog""" QDialog.close(self)
class DatePicker(QWidget): selectionChanged = Signal() def __init__(self, parent=None): super(DatePicker, self).__init__(parent) self.button = QPushButton(self) icon = QIcon("logo.svg") self.button.setIcon(icon) self.setFixedSize(32, 32) self.button.setFixedSize(32, 32) self.button.setIconSize(QSize(22, 22)) self.__margin__ = 5 self.dialog = QDialog() self.dialog.setWindowFlags(Qt.Window | Qt.FramelessWindowHint | Qt.Popup) self.dialog.setFixedSize(480, 240) self.dialog.setLayout(QHBoxLayout()) self.calender = QCalendarWidget(self) self.dialog.layout().addWidget(self.calender) self.dialog.layout().setContentsMargins(0, 0, 0, 0) self.dialog.layout().setSpacing(0) self.button.clicked.connect(self.showCalender) self.calender.selectionChanged.connect(self.__onSelectionChanged__) def show(self): self.showCalender() def close(self): self.dialog.close() @Slot() def showCalender(self): print('in show') p = self.mapToGlobal(QPoint(0, self.height() + self.__margin__)) self.dialog.setGeometry(p.x(), p.y(), 0, 0) self.dialog.show() def setIcon(self, icon): if type(icon) is QIcon: self.button.setIcon(icon) elif type(icon) is str: self.button.setIcon(QIcon(icon)) else: raise Exception( 'Wrong argument type, icon should be either PySide2.QtGui.QIcon or str "string"' ) def icon(self): return self.button.icon() def setIconSize(self, iconSize): self.button.setIconSize(iconSize) # if type(iconSize) is QSize: # self.button.setIconSize(iconSize) # elif type(iconSize) is int: # self.button.setIcon(QSize(iconSize, iconSize)) # elif type(type) is iter: # import collections # if isinstance(iconSize, collections.Iterable): # if len(iconSize) == 1: # self.setIconSize(iconSize[0]) # elif len(iconSize) == 2: # self.setIconSize(QSize(iconSize[0], iconSize[1])) # else: # raise Exception() # else: # raise Exception("Wrong argument type, iconSize should be either PySide2.QtCore.QSize or int value or width and height " # "or iterable contains one QSize, one int or two int values for width and height respectively") def iconSize(self): return self.button.iconSize() def setFirstDayOfWeek(self, firstDayOfWeek): self.calender.setFirstDayOfWeek(firstDayOfWeek) # if type(firstDayOfWeek) is Qt.DayOfWeek: # self.calender.setFirstDayOfWeek(firstDayOfWeek) # elif type(firstDayOfWeek) is int: # if firstDayOfWeek < 1 or firstDayOfWeek > 7: # raise Exception("Wrong argument, firstDayOfWeek should be from 1 to 7 (Monday --> Sunday)") # self.calender.setFirstDayOfWeek(Qt.DayOfWeek(firstDayOfWeek)) # else: # raise Exception("Wrong type, firstDayOfWeek should be either PySide2.QtCore.Qt.DayOf or int (1 --> 7) (Monday --> Sunday)") def firstDayOfWeek(self): self.calender.firstDayOfWeek() def selectedDate(self): self.calender.selectedDate() def setSelectedDate(self, args, kwargs): self.calender.setSelectedDate(args, kwargs) def minimumDate(self): self.calender.minimumDate() def setMinimumDate(self): self.calender.setMinimumDate() def __onSelectionChanged__(self): self.selectionChanged.emit()
class Start(QWidget): def __init__(self): super().__init__() self.setWindowTitle('扫雷') self.setWindowIcon(QIcon(':/minesweeper.ico')) self.setFixedSize(1000, 700) self.setMouseTracking(True) self.setWindowFlags(Qt.FramelessWindowHint) self.btn = QPushButton(self) self.btn.setMouseTracking(True) self.btn.setIcon(QIcon(':/开始游戏.png')) self.btn.setIconSize(QSize(280, 200)) self.btn.setStyleSheet('QPushButton{border:None}') self.btn.move(350, 370) self.btn.clicked.connect(self.show_mode) self.msw = MineSweeperWindow(MineSweeper(0, 0, 0)) self.show() def show_mode(self): self.choose = QDialog() self.choose.setWindowIcon(QIcon(':/minesweeper.ico')) self.choose.setFixedSize(300, 300) self.close() btn1 = QPushButton('简单', self.choose) btn1.move(90, 50) btn1.clicked.connect(self.set_easy) btn2 = QPushButton('中等', self.choose) btn2.move(90, 100) btn2.clicked.connect(self.set_medium) btn3 = QPushButton('困难', self.choose) btn3.move(90, 150) btn3.clicked.connect(self.set_hard) btn4 = QPushButton('自定义', self.choose) btn4.move(90, 200) btn4.clicked.connect(self.set_free) self.choose.setWindowTitle('模式选择') self.choose.setWindowModality(Qt.ApplicationModal) self.choose.show() def paintEvent(self, e): painter = QPainter(self) background = QPixmap(':/封面2.jpg') painter.drawPixmap(self.rect(), background) def mouseMoveEvent(self, e): if 400 <= e.x() <= 580 and 420 <= e.y() <= 520: self.btn.setGeometry(340, 366, 300, 214) self.btn.setIconSize(QSize(300, 214)) else: self.btn.setGeometry(350, 370, 280, 200) self.btn.setIconSize(QSize(280, 200)) def set_easy(self): self.choose.close() self.msw = MineSweeperWindow(EasyMode()) self.msw.show() def set_medium(self): self.choose.close() self.msw = MineSweeperWindow(MediumMode()) self.msw.show() def set_hard(self): self.choose.close() self.msw = MineSweeperWindow(HardMode()) self.msw.show() def set_free(self): self.sf = SetFree() self.choose.close() self.sf.show()