从过程向标签输出文本

0 投票
1 回答
2567 浏览
提问于 2025-04-30 18:17

谢谢你们到目前为止的帮助!还有一个问题解决了就可以收尾了。

我找不到办法把文本输出到标签上,如果可以的话,我还想在那个标签里显示一个链接,让用户可以打开网页。

我试着定义新的程序来实现这个功能,但在构建时虽然可以指定文本,之后我却无法更改它!我总是收到“变量未定义”的错误,显然我在错误的地方操作了!

import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.spinner import Spinner
from bs4 import BeautifulSoup
from urllib import request
import sys, traceback
from functools import partial
import re
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.image import Image


class DSFRSapp(App):
    def build(self):
        self.root = FloatLayout()
        i = Image(source='DSFRSLogo.png',
                  allow_stretch=True,
                  pos_hint = ({'center_x':0.5, 'y': .25}))
        spinner = Spinner(text='Select a Station',
                             values=('Appledore','Axminster','Bampton','Barnstaple','Bere Alston','Bideford','Bovey Tracey','Braunton','Bridgwater','Brixham','Buckfastleigh','Budleigh Salterton','Burnham on sea','Camels Head','Castle Cary','Chagford','Chard','Cheddar','Chulmleigh','Colyton','Combe Martin','Crediton','Crewkerne','Crownhill','Cullompton','Dartmouth','Dawlish','Exeter Danes Castle','Exeter Middlemoor','Exmouth','Frome','Glastonbury','Greenbank','Hartland','Hatherleigh','Holsworthy','Honiton','Ilfracombe','Ilminster','Ivybridge','Kingsbridge','Kingston','Lundy Island','Lynton','Martock','Minehead','Modbury','Moretonhampstead','Nether Stowey','Newton Abbot','North Tawton','Okehampton','Ottery St Mary','Paignton','Plympton','Plymstock','Porlock','Princetown','Salcombe','Seaton','Shepton Mallet','Sidmouth','Somerton','South Molton','Street','Taunton','Tavistock','Teignmouth','Tiverton','Topsham','Torquay','Torrington','Totnes','USAR','Wellington','Wells','Williton','Wincanton','Witheridge','Wiveliscombe','Woolacombe','Yelverton','Yeovil'),
                            size_hint=(None, None),
                            size=(150, 44),
                            pos_hint = ({'center_x':0.5, 'y': 0.35}))
        L = Label(text="Results will display here",
                      size_hint=(None, None),
                      pos_hint =({'center_x':0.5, 'y': 0.25}),
                      size=(150, 44))
        self.root.add_widget(spinner)
        self.root.add_widget(L)
        self.root.add_widget(i)
        spinner.bind(text=show_selected_value)



def show_selected_value(spinner, text):
    FindIncident(text)


def FindIncident( sStation, *args ):
    webpage = request.urlopen("http://www.dsfire.gov.uk/News/Newsdesk/IncidentsPast7days.cfm?siteCategoryId=3&T1ID=26&T2ID=35")#main page
    soup = BeautifulSoup(webpage)
    incidents = soup.find(id="CollapsiblePanel1") #gets todays incidents panel
    Links = [] #create list call Links

    for line in incidents.find_all('a'): #get all hyperlinks
        Links.append("http://www.dsfire.gov.uk/News/Newsdesk/"+line.get('href')) #loads links into Links list while making them full links
    n = 0
    e = len(Links)
    if e == n: #if no links available no need to continue
    #output message to label
       print("nothing found please try again later")
       sys.exit(0)
    sFound = False
    while n < e: #loop through links to find station
        if sFound: #if the station has been found stop looking
             sys.exit(0)
        webpage = request.urlopen(Links[n]) #opens link in list)
        soup = BeautifulSoup(webpage) #loads webpage
        if soup.find_all('p', text=re.compile(r'{}'.format(sStation))) == []:#check if returned value is found
        #do nothing leaving blank gave error
            a = "1" #this is pointless but stops the error
        else:
            print(soup.find_all('p', text=re.compile(r'{}'.format(sStation))))
            WebLink = Links[n]
            sFound = True # to avoid un needed goes through the loop process
        n=n+1 # moves counter to next in list
    if not sFound: #after looping process if nothing has been found output nothing found
        print("nothing found please try again later ")
    #output to label
    return;



if __name__ =="__main__":
    DSFRSapp().run()

我还得提一下,我有一个会显示的logo,我会在屏幕调整大小时更好地放置这些小部件。我想把背景颜色设为白色,可能加上一个细细的红色边框(就是想让它看起来更好看一些)。

如果你能回答这些问题中的任何一个,那就太好了!不过目前最重要的是把网页搜索的结果输出到标签上,而不是打印到控制台,最好还能带上链接(WebLink)。

再次感谢,一旦我解决了这些问题,我打算把这个程序交给我的消防服务部门,让消防员的伴侣们能大致了解消防员什么时候可能结束工作。不过这得等我能把它打包成安卓应用,也许还要找其他人把它移植到iOS,因为我没有Mac电脑。

暂无标签

1 个回答

0

我对代码做了一些修改,让它更符合Python的风格,特别是在循环方面。现在标签已经连接上了,但我还没有尝试调试你的网页抓取部分。这个你得自己再检查一下。

import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.spinner import Spinner
from bs4 import BeautifulSoup
from urllib import request
import sys, traceback
from functools import partial
import re
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.image import Image
from kivy.properties import ObjectProperty

kv = '''
<IncidentScreen>:
    station: stationSpinner
    results: resultsLabel
    Image:
        source:'DSFRSLogo.png'
        allow_stretch:True
        pos_hint: {'center_x':0.5, 'y': .25}

    Spinner:
        id: stationSpinner
        text:'Select a Station'
        values: ('Appledore','Axminster','Bampton','Barnstaple','Bere Alston','Bideford','Bovey Tracey','Braunton','Bridgwater','Brixham','Buckfastleigh','Budleigh Salterton','Burnham on sea','Camels Head','Castle Cary','Chagford','Chard','Cheddar','Chulmleigh','Colyton','Combe Martin','Crediton','Crewkerne','Crownhill','Cullompton','Dartmouth','Dawlish','Exeter Danes Castle','Exeter Middlemoor','Exmouth','Frome','Glastonbury','Greenbank','Hartland','Hatherleigh','Holsworthy','Honiton','Ilfracombe','Ilminster','Ivybridge','Kingsbridge','Kingston','Lundy Island','Lynton','Martock','Minehead','Modbury','Moretonhampstead','Nether Stowey','Newton Abbot','North Tawton','Okehampton','Ottery St Mary','Paignton','Plympton','Plymstock','Porlock','Princetown','Salcombe','Seaton','Shepton Mallet','Sidmouth','Somerton','South Molton','Street','Taunton','Tavistock','Teignmouth','Tiverton','Topsham','Torquay','Torrington','Totnes','USAR','Wellington','Wells','Williton','Wincanton','Witheridge','Wiveliscombe','Woolacombe','Yelverton','Yeovil')
        size_hint: None, None
        size: (150, 44)
        pos_hint: {'center_x':0.5, 'y': 0.35}
        on_text: app.show_selected_value()

    Label:
        id: resultsLabel
        text:"Results will display here"
        color: [0,0,0,1]
        size_hint:(None, None)
        pos_hint:{'center_x':0.5, 'y': 0.25}
        size: (150, 44)

'''
class IncidentScreen(FloatLayout):
    station = ObjectProperty(None)
    results = ObjectProperty(None)

class DSFRSapp(App):

    def build(self):
        Builder.load_string(kv)
        fl = IncidentScreen()
        return fl

    def show_selected_value(self):
        incident = self.FindIncident(self.root.station.text)
        if incident:
            self.root.results.text = incident
        else:
            self.root.results.text = 'Try again later'

    def FindIncident(self, sStation, *args ):
        webpage = request.urlopen("http://www.dsfire.gov.uk/News/Newsdesk/IncidentsPast7days.cfm?siteCategoryId=3&T1ID=26&T2ID=35")#main page
        soup = BeautifulSoup(webpage)
        incidents = soup.find(id="CollapsiblePanel1") #gets todays incidents panel
        #create list call Links

        #get all hyperlinks: loads links into Links list while making them full links
        Links = [''.join(["http://www.dsfire.gov.uk/News/Newsdesk/",line.get('href')]) for line in incidents.find_all('a')]

        #loop through links to find station
        incident = ''
        for link in Links:
            print('Trying {}'.format(link))
            webpage = request.urlopen(link) #opens link in list)
            soup = BeautifulSoup(webpage) #loads webpage

            #check if returned value is found
            incident = soup.find_all('p', text=re.compile(r'{}'.format(sStation)))
            print(incident)
            break

        return incident



if __name__ =="__main__":
    DSFRSapp().run()

这里有一些重要的注意事项:

  1. 你提到想把这个打包成安卓应用,但你似乎在用Python3的语法。根据我所知,目前kivy只支持在Python2下运行安卓应用。
  2. 我建议至少要有一些基本的错误处理,比如在网页解析时没有处理异常。
  3. 你用来收集事件的网站已经有了xml数据源。直接解析这个数据源会更好,可以更方便地获取事件列表。
  4. kivy语言在创建复杂的图形界面配置方面要好得多。我建议把kv字符串中的所有内容移到一个名为DSFR.kv的单独文件中。这样你就可以删除Builder.loadstring这一行了。这也会让你更容易进行你在问题中提到的额外修改。
  5. 我不建议直接把下拉框和网页查询绑定在一起,因为如果网页请求花费的时间太长,程序会卡住。我建议使用一个屏幕管理器,设置一个单独的结果屏幕,并通过下拉框来触发切换。
  6. 连续向一个网站发送多个查询请求可能会导致你的应用或IP地址被网站管理员列入黑名单。请小心处理这个问题。

额外问题:

撰写回答