多线程传递datetime的问题
main.pyimport sys
import time
import datetime
import requests
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Worker(QThread):
# 这里返回 Date 类型,该如何写?
finishSignal = pyqtSignal()
def __init__(self, timeNow,timeMiaosha,parent=None):
super(Worker, self).__init__(parent)
def run(self):
time.sleep(0.1)
#获得北京时间
try:
url = 'htt_ps://beijing-time.org/' #这里我不能发布链接,请自行修改一些
request_result = requests.get(url=url)
if request_result.status_code == 200:
headers = request_result.headers
net_date = headers.get("date")
gmt_time = time.strptime(net_date, "%d %b %Y %H:%M:%S")
bj_timestamp = int(time.mktime(gmt_time) + 8 * 60 * 60)
#return datetime.datetime.fromtimestamp(bj_timestamp)
self.finishSignal.emit(datetime.datetime.fromtimestamp(bj_timestamp))
except Exception as exc:
#return datetime.datetime.now()
self.finishSignal.emit(datetime.datetime.now())
class MyWindow(QWidget):
# 初始化
def __init__(self):
super().__init__()
self.load_ui()
def load_ui(self):
#读取ui界面
self.ui = uic.loadUi("main.ui")
# 绑定北京和本地时间框
# hh:mm:ss.zzz
self.dateTimeBeijing = self.ui.dateTimeBeijing
self.dateTimeBeijing.setDisplayFormat("yyyy-MM-dd HH:mm:ss.zzz")
self.dateTimeCur = self.ui.dateTimeCur
self.dateTimeCur.setDisplayFormat("yyyy-MM-dd HH:mm:ss.zzz")
#设置1个定时器,用于更新本地时间
timerNow = QTimer(self)
timerNow.timeout.connect(self.timeNow)
timerNow.start()
# 这里出错
self.thread = Worker()
self.thread.sig.connect(self.timeBJ)
self.thread.start()
#显示当前时间
def timeNow(self):
self.cur_time = QDateTime.currentDateTime()
self.dateTimeCur.setDateTime(self.cur_time)
#显示当前的北京时间
def timeBJ(self,msg):
self.dateTimeBeijing.setDateTime(msg)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.ui.show()
sys.exit(app.exec())
main.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>289</width>
<height>108</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
</font>
</property>
<property name="windowTitle">
<string>测试</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QLabel" name="labelCur">
<property name="text">
<string>本机时间</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QDateTimeEdit" name="dateTimeCur">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QDateTimeEdit" name="dateTimeBeijing">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelBeijing">
<property name="text">
<string>北京时间</string>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>dateTimeBeijing</tabstop>
<tabstop>dateTimeCur</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
请教,多线程传递datetime,却一直出错。该如何修改代码呢(信号和槽没有掌握哎)?
很高兴帮你解答问题!在这个代码中,你使用了PyQt5库来创建一个应用程序界面,并使用多线程来获取北京时间并更新界面上的日期时间编辑器。根据你的描述,你遇到了一些问题,需要修改代码。
根据你提供的代码,有几个地方需要进行修改:
首先,在Worker类中,你定义了一个信号finishSignal,但是在连接信号和槽时使用了错误的信号名称sig,你应该将其改为finishSignal。修改后的代码如下:
self.thread = Worker()
self.thread.finishSignal.connect(self.timeBJ)
self.thread.start()
其次,在Worker类的run方法中,当使用emit方法发送信号时,需要传递正确的参数类型。你可以使用pyqtSignal的参数列表来指定要传递的数据类型。在这种情况下,你可以使用pyqtSignal(datetime.datetime)来定义信号。修改后的代码如下:
class Worker(QThread):
finishSignal = pyqtSignal(datetime.datetime)
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
def run(self):
time.sleep(0.1)
try:
url = 'https://beijing-time.org/'
request_result = requests.get(url=url)
if request_result.status_code == 200:
headers = request_result.headers
net_date = headers.get("date")
gmt_time = time.strptime(net_date, "%d %b %Y %H:%M:%S")
bj_timestamp = int(time.mktime(gmt_time) + 8 * 60 * 60)
self.finishSignal.emit(datetime.datetime.fromtimestamp(bj_timestamp))
except Exception as exc:
self.finishSignal.emit(datetime.datetime.now())
通过这些修改,你应该能够解决多线程传递datetime的问题。尝试运行修改后的代码,看看是否能够正常获取和显示北京时间。如果还有其他问题,请随时向我提问! 多线程传递datetime的问题 Python交流
你的代码中出现了一些问题。首先,在Worker类中,你定义了一个finishSignal信号,但是在连接信号和槽时使用了错误的信号名称。应该将self.thread.sig.connect(self.timeBJ)修改为self.thread.finishSignal.connect(self.timeBJ)。
另外,你在Worker类的run方法中使用了time.sleep(0.1),这会导致主线程被阻塞,界面无法响应。你可以考虑在请求北京时间之前使用QCoreApplication.processEvents()来处理事件循环,以确保界面仍然可以响应。
最后,在Worker类的run方法中,你发射了一个finishSignal信号,并传递了一个datetime对象作为参数。但是在连接信号和槽时,你定义的槽函数需要一个字符串参数,而不是datetime对象。你可以修改timeBJ方法的签名,将参数类型改为datetime。
下面是修改后的代码示例:
import sys
import time
import datetime
import requests
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Worker(QThread):
finishSignal = pyqtSignal(datetime.datetime)
def run(self):
# 获得北京时间
try:
url = 'https://beijing-time.org/'
request_result = requests.get(url=url)
if request_result.status_code == 200:
headers = request_result.headers
net_date = headers.get("date")
gmt_time = time.strptime(net_date, "%d %b %Y %H:%M:%S")
bj_timestamp = int(time.mktime(gmt_time) + 8 * 60 * 60)
bj_datetime = datetime.datetime.fromtimestamp(bj_timestamp)
self.finishSignal.emit(bj_datetime)
except Exception as exc:
self.finishSignal.emit(datetime.datetime.now())
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.load_ui()
self.thread = Worker()
self.thread.finishSignal.connect(self.timeBJ)
self.thread.start()
def load_ui(self):
self.ui = uic.loadUi("main.ui")
self.dateTimeBeijing = self.ui.dateTimeBeijing
self.dateTimeBeijing.setDisplayFormat("yyyy-MM-dd HH:mm:ss.zzz")
self.dateTimeCur = self.ui.dateTimeCur
self.dateTimeCur.setDisplayFormat("yyyy-MM-dd HH:mm:ss.zzz")
timerNow = QTimer(self)
timerNow.timeout.connect(self.timeNow)
timerNow.start()
def timeNow(self):
self.cur_time = QDateTime.currentDateTime()
self.dateTimeCur.setDateTime(self.cur_time)
def timeBJ(self, msg: datetime.datetime):
self.dateTimeBeijing.setDateTime(msg)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.ui.show()
sys.exit(app.exec())
通过上述修改,你的多线程传递datetime的问题应该可以解决了。希望对你有帮助!如有更多问题,请随时提问。
球一个最佳答案谢谢啦!这对我非常重要!{:10_254:}{:10_254:}{:10_254:}
根据您提供的代码,有几个问题需要修复。
首先,在`Worker`类中,您定义了一个`finishSignal`信号,但是在连接信号和槽时,使用了错误的信号名称。在主窗口的`load_ui`函数中,将`self.thread.sig`改为`self.thread.finishSignal`。
其次,由于信号与槽函数的参数不匹配,需要调整`timeBJ`函数的参数。根据您的代码,`msg`参数应该为`datetime.datetime`类型,所以将`timeBJ`函数的定义修改为`def timeBJ(self, msg: datetime.datetime)`。
接下来是关于多线程的使用。您在主窗口中创建了一个`Worker`对象,并将其连接到一个定时器的超时槽函数中。但实际上,您的定时器并不需要用到多线程。您可以直接在定时器的槽函数中获取北京时间,而不需要启动一个新的线程。
最后,当您想要更新界面上的时间时,需要在主线程中执行更新操作。在`timeNow`和修正后的`timeBJ`函数中,使用`self.dateTimeCur`和`self.dateTimeBeijing`的`setDateTime`方法更新时间。
下面是修复后的代码:
```python
import sys
import time
import datetime
import requests
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Worker(QThread):
finishSignal = pyqtSignal(datetime.datetime)
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
def run(self):
time.sleep(0.1)
try:
url = 'htt_ps://beijing-time.org/' #这里我不能发布链接,请自行修改一些
request_result = requests.get(url=url)
if request_result.status_code == 200:
headers = request_result.headers
net_date = headers.get("date")
gmt_time = time.strptime(net_date, "%d %b %Y %H:%M:%S")
bj_timestamp = int(time.mktime(gmt_time) + 8 * 60 * 60)
self.finishSignal.emit(datetime.datetime.fromtimestamp(bj_timestamp))
except Exception as exc:
self.finishSignal.emit(datetime.datetime.now())
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.load_ui()
def load_ui(self):
self.ui = uic.loadUi("main.ui")
self.dateTimeBeijing = self.ui.dateTimeBeijing
self.dateTimeBeijing.setDisplayFormat("yyyy-MM-dd HH:mm:ss.zzz")
self.dateTimeCur = self.ui.dateTimeCur
self.dateTimeCur.setDisplayFormat("yyyy-MM-dd HH:mm:ss.zzz")
timerNow = QTimer(self)
timerNow.timeout.connect(self.timeNow)
timerNow.start()
self.worker = Worker()
self.worker.finishSignal.connect(self.timeBJ)
self.worker.start()
def timeNow(self):
self.cur_time = QDateTime.currentDateTime()
self.dateTimeCur.setDateTime(self.cur_time)
def timeBJ(self, msg: datetime.datetime):
self.dateTimeBeijing.setDateTime(msg)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.ui.show()
sys.exit(app.exec())
```
请尝试使用修复后的代码,并确保您的PyQt5版本已正确安装。如果仍然遇到问题,请提供完整的错误信息以便进一步帮助您解决问题。
求给个最佳答案呗{:10_254:}
此回答源于ChatGPT,若有不正确之处,请多包容 在这段代码中,错误可能源自两个主要原因:
1.pyqtSignal()对象的声明没有明确参数类型。信号可以传递任何类型的数据,包括datetime ,只需在pyqtSignal()中指定类型即可。
2.Worker线程的初始化中没有接受任何参数,而在实例化Worker的时候并没有提供所需的参数。
所以,我们可以这样修改你的代码:
# 在 Worker 类定义中添加 datetime 类型的信号
class Worker(QThread):
finishSignal = pyqtSignal(datetime)
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
def run(self):
time.sleep(0.1)
try:
url = 'htt_ps://beijing-time.org/' #这里我不能发布链接,请自行修改一些
request_result = requests.get(url=url)
if request_result.status_code == 200:
headers = request_result.headers
net_date = headers.get("date")
gmt_time = time.strptime(net_date, "%d %b %Y %H:%M:%S")
bj_timestamp = int(time.mktime(gmt_time) + 8 * 60 * 60)
self.finishSignal.emit(datetime.datetime.fromtimestamp(bj_timestamp))
except Exception as exc:
self.finishSignal.emit(datetime.datetime.now())
在 MyWindow 类中,连接信号和槽:
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.load_ui()
self.thread = Worker()
self.thread.finishSignal.connect(self.timeBJ)
self.thread.start()
def timeBJ(self, time_bj):
self.dateTimeBeijing.setDateTime(QDateTime(time_bj))
修改后的代码首先确保了Worker类中的信号是datetime类型,并且在MyWindow类中正确地连接了finishSignal信号和timeBJ方法。 timeBJ方法接受datetime类型的参数,将其转换为QDateTime类型并设置到dateTimeBeijing控件中。
请注意,你需要处理异常的情况,当请求北京时间失败时,应将问题报告给用户,而不是简单地用本地时间代替。此外,这个方法获取北京时间可能不完全准确,因为它依赖于服务器返回的 "Date" 头部信息,并假设服务器位于 GMT 时区。如果你需要准确的北京时间,可能需要使用一个提供这项服务的 API。 本帖最后由 fengma 于 2023-7-20 13:59 编辑
self.thread.finishSignal.connect(self.timeBJ)
这里是失误了。
finishSignal = pyqtSignal(datetime.datetime)
def timeBJ(self, msg: datetime.datetime):
这里我就真的不会了。受教了!pyqtSignal有学习的吗?
刚学python(pyqt5),还是得买1本的书好好学习一下呀。大家有推荐的书籍吗?
页:
[1]