基于javafx如何用线程完成移动一个圆?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于javafx如何用线程完成移动一个圆?相关的知识,希望对你有一定的参考价值。
运用JavaFX技术设计如图3所示简单动画(动画效果见视频 移动的圆.avi)。窗口宽400,高200,圆半径50,圆心纵坐标100,圆边框黑色线宽3像素。移动速度:1像素/20毫秒。
利用“绘图”菜单可以插入线段,方法如下: 1、单击“绘图”菜单下的“自选图形”,选择“线条”菜单下的“直线” 2、屏幕中出现“在此处创建图形”,我们不利用这个文本框调整线条的位置,在这个文本档的下方绘制线段 3、在文本框的下方,按住鼠标左键同时. 参考技术A 可以在“按钮点击事件”中写上读取fmxl为节点对象 Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml")); 然后把父节点放入某个new Scene(root,320,200); 然后在显示在所用的舞台stage上。我如何用 pafy 为进度条制作线程
【中文标题】我如何用 pafy 为进度条制作线程【英文标题】:how i can make thread for progress bar with pafy 【发布时间】:2019-01-04 14:55:11 【问题描述】:我正在尝试解决我的程序中的问题,这个问题是当我开始下载视频时,程序没有响应,我也看不到进度条移动,所以我尝试使用线程模块,但我无法解决问题所以我该如何解决问题
通过此代码,我可以下载视频并将数据发送到另一个函数,以检索我用来将其连接到进度条的信息
def video(self):
video_url = self.lineEdit_4.text()
video_save = self.lineEdit_3.text()
pafy_video = pafy.new(video_url)
type_video = pafy_video.videostreams
quality = self.comboBox.currentIndex()
start_download = type_video[quality].download(filepath=video_save,callback=self.video_progressbar)
此代码是从视频功能接收信息以连接进度条
def video_progressbar(self,total, recvd, ratio, rate, eta):
self.progressBar_2.setValue(ratio * 100)
我用;python3.5 pyqt5 pafy
【问题讨论】:
【参考方案1】:移动到另一个线程的一种方法是创建一个位于另一个线程中的QObject
,并在一个槽中执行该任务。并且该槽必须通过QMetaObject::invokeMethod
或信号调用。
with QThread and QMetaObject::invokeMethod:
import pafy
from PyQt5 import QtCore, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
self.le_url = QtWidgets.QLineEdit("https://www.youtube.com/watch?v=bMt47wvK6u0")
path = QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.DownloadLocation)
self.le_output = QtWidgets.QLineEdit(path)
self.btn_quality = QtWidgets.QPushButton("Get qualities")
self.combo_quality = QtWidgets.QComboBox()
self.btn_download = QtWidgets.QPushButton("Download")
self.progressbar = QtWidgets.QProgressBar(maximum=100)
self.downloader = DownLoader()
thread = QtCore.QThread(self)
thread.start()
self.downloader.moveToThread(thread)
self.btn_quality.clicked.connect(self.on_clicked_quality)
self.btn_download.clicked.connect(self.download)
self.btn_download.setDisabled(True)
self.downloader.progressChanged.connect(self.progressbar.setValue)
self.downloader.qualitiesChanged.connect(self.update_qualityes)
self.downloader.finished.connect(self.on_finished)
form_lay = QtWidgets.QFormLayout(central_widget)
form_lay.addRow("Url: ", self.le_url)
form_lay.addRow(self.btn_quality)
form_lay.addRow("qualities: ", self.combo_quality)
form_lay.addRow("Output: ", self.le_output)
form_lay.addRow(self.btn_download)
form_lay.addRow(self.progressbar)
@QtCore.pyqtSlot()
def on_finished(self):
self.update_disables(False)
@QtCore.pyqtSlot()
def on_clicked_quality(self):
video_url = self.le_url.text()
QtCore.QMetaObject.invokeMethod(self.downloader, "get_qualities",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, video_url))
@QtCore.pyqtSlot(list)
def update_qualityes(self, types_of_video):
for t in types_of_video:
self.combo_quality.addItem(str(t), t)
self.btn_download.setDisabled(False)
@QtCore.pyqtSlot()
def download(self):
video_save = self.le_output.text()
d = self.combo_quality.currentData()
QtCore.QMetaObject.invokeMethod(self.downloader, "start_download",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(object, d),
QtCore.Q_ARG(str, video_save))
self.update_disables(True)
def update_disables(self, state):
self.combo_quality.setDisabled(state)
self.btn_quality.setDisabled(state)
self.le_output.setDisabled(state)
self.le_url.setDisabled(state)
self.btn_download.setDisabled(not state)
class DownLoader(QtCore.QObject):
progressChanged = QtCore.pyqtSignal(int)
qualitiesChanged = QtCore.pyqtSignal(list)
finished = QtCore.pyqtSignal()
@QtCore.pyqtSlot(str)
def get_qualities(self, video_url):
pafy_video = pafy.new(video_url)
types_of_video = pafy_video.allstreams # videostreams
self.qualitiesChanged.emit(types_of_video)
@QtCore.pyqtSlot(object, str)
def start_download(self, d, filepath):
d.download(filepath=filepath, callback=self.callback)
def callback(self, total, recvd, ratio, rate, eta):
val = int(ratio * 100)
self.progressChanged.emit(val)
if val == 100:
self.finished.emit()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(320, 480)
w.show()
sys.exit(app.exec_())
with threading.Thread
:
import pafy
import threading
from PyQt5 import QtCore, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
qualitiesChanged = QtCore.pyqtSignal(list)
progressChanged = QtCore.pyqtSignal(int)
finished = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
self.le_url = QtWidgets.QLineEdit("https://www.youtube.com/watch?v=bMt47wvK6u0")
path = QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.DownloadLocation)
self.le_output = QtWidgets.QLineEdit(path)
self.btn_quality = QtWidgets.QPushButton("Get qualities")
self.combo_quality = QtWidgets.QComboBox()
self.btn_download = QtWidgets.QPushButton("Download")
self.progressbar = QtWidgets.QProgressBar(maximum=100)
self.btn_quality.clicked.connect(self.on_clicked_quality)
self.btn_download.clicked.connect(self.download)
self.btn_download.setDisabled(True)
self.progressChanged.connect(self.progressbar.setValue)
self.qualitiesChanged.connect(self.update_qualityes)
self.finished.connect(self.on_finished)
form_lay = QtWidgets.QFormLayout(central_widget)
form_lay.addRow("Url: ", self.le_url)
form_lay.addRow(self.btn_quality)
form_lay.addRow("qualities: ", self.combo_quality)
form_lay.addRow("Output: ", self.le_output)
form_lay.addRow(self.btn_download)
form_lay.addRow(self.progressbar)
@QtCore.pyqtSlot()
def on_finished(self):
self.update_disables(False)
@QtCore.pyqtSlot()
def on_clicked_quality(self):
video_url = self.le_url.text()
threading.Thread(target=self.get_qualities, args=(video_url,)).start()
def get_qualities(self, video_url):
pafy_video = pafy.new(video_url)
types_of_video = pafy_video.allstreams # videostreams
self.qualitiesChanged.emit(types_of_video)
@QtCore.pyqtSlot(list)
def update_qualityes(self, types_of_video):
for t in types_of_video:
self.combo_quality.addItem(str(t), t)
self.btn_download.setDisabled(False)
@QtCore.pyqtSlot()
def download(self):
video_save = self.le_output.text()
d = self.combo_quality.currentData()
threading.Thread(target=d.download, kwargs='filepath': video_save, 'callback': self.callback, daemon=True).start()
def callback(self, total, recvd, ratio, rate, eta):
print(ratio)
val = int(ratio * 100)
self.progressChanged.emit(val)
if val == 100:
self.finished.emit()
def update_disables(self, state):
self.combo_quality.setDisabled(state)
self.btn_quality.setDisabled(state)
self.le_output.setDisabled(state)
self.le_url.setDisabled(state)
self.btn_download.setDisabled(not state)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(320, 480)
w.show()
sys.exit(app.exec_())
【讨论】:
感谢您的代码运行良好,但我的代码无法使用 qthread,我使用的是 QmainWindow 因为我理解你是50%的代码所以我尝试使用qthread,并没有成功解决无响应问题 你刚换了课 我会把我的代码交给你解决我的问题,并将 qthread 放在正确的位置 谢谢你,我再次尝试阅读你的代码,我现在明白了如何使用线程以上是关于基于javafx如何用线程完成移动一个圆?的主要内容,如果未能解决你的问题,请参考以下文章
如何用Python一门语言通吃高性能并发,GPU计算和深度学习