主頁 > 軟體設計 > 模擬全域鍵盤按下

模擬全域鍵盤按下

2021-11-01 02:17:49 軟體設計

我正在 mac 上構建一個 swiftUI 應用程式,我想知道是否有辦法在應用程式運行時或在后臺模擬鍵盤快捷鍵。我使用這個應用程式的目標是在我的服務器向我發送相應的手勢資訊時呼叫快捷方式。我正在考慮使用,NSEvent.addGlobalMonitorForEvents(matching: .keyDown, handler: self.handler)但我認為這更多的是重新編程快捷方式,而不僅僅是呼叫它們。

例如,如果我的服務器向我發送了一個字串,上面寫著“粘貼”,那么無論我在哪個螢屏上,只要我的應用程式正在運行,我將如何呼叫命令粘貼快捷方式。任何幫助或資訊將不勝感激!

uj5u.com熱心網友回復:

我的 Mac 上有這個游樂場,所以我想在這里分享一下,以防萬一:

import Cocoa

let src = CGEventSource(stateID: .hidSystemState)

let down = CGEvent(keyboardEventSource: src, virtualKey: 0x12, keyDown: true)!
let up = CGEvent(keyboardEventSource: src, virtualKey: 0x12, keyDown: false)!

sleep(5)

////down?.post(tap: .cghidEventTap)
////up?.post(tap: .cghidEventTap)
////down?.flags = .maskCommand
//
//let cmd_d = CGEvent(keyboardEventSource: src, virtualKey: 0x37, keyDown: true)!
//let cmd_u = CGEvent(keyboardEventSource: src, virtualKey: 0x37, keyDown: false)!
//let a_d = CGEvent(keyboardEventSource: src, virtualKey: 0x00, keyDown: true)!
//let a_u = CGEvent(keyboardEventSource: src, virtualKey: 0x00, keyDown: false)!
//let delete_d = CGEvent(keyboardEventSource: src, virtualKey: 0x33, keyDown: true)!
//let delete_u = CGEvent(keyboardEventSource: src, virtualKey: 0x33, keyDown: false)!
//
//down.post(tap: .cghidEventTap)
//up.post(tap: .cghidEventTap)
//sleep(1)
////cmd_d.post(tap: .cghidEventTap)
//a_d.flags = .maskCommand
//a_u.flags = .maskCommand
//a_d.post(tap: .cghidEventTap)
//a_u.post(tap: .cghidEventTap)
////cmd_u.post(tap: .cghidEventTap)
//sleep(1)
//delete_d.post(tap: .cghidEventTap)
//delete_u.post(tap: .cghidEventTap)

enum KeyCode: UInt16 {
    // https://gist.github.com/swillits/df648e87016772c7f7e5dbed2b345066

    // Layout-independent Keys
    // eg.These key codes are always the same key on all layouts.
    case returnKey = 0x24
//    case enter = 0x4C //0x24
    case tab = 0x30
    case space = 0x31
    case delete = 0x33
    case escape = 0x35
    case command = 0x37
    case shift = 0x38
    case capsLock = 0x39
    case option = 0x3A
    case control = 0x3B
    case rightShift = 0x3C
    case rightOption = 0x3D
    case rightControl = 0x3E
    case leftArrow = 0x7B
    case rightArrow = 0x7C
    case downArrow = 0x7D
    case upArrow = 0x7E
    case volumeUp = 0x48
    case volumeDown = 0x49
    case mute = 0x4A
    case help = 0x72
    case home = 0x73
    case pageUp = 0x74
    case forwardDelete = 0x75
    case end = 0x77
    case pageDown = 0x79
    case function = 0x3F
    case f1 = 0x7A
    case f2 = 0x78
    case f4 = 0x76
    case f5 = 0x60
    case f6 = 0x61
    case f7 = 0x62
    case f3 = 0x63
    case f8 = 0x64
    case f9 = 0x65
    case f10 = 0x6D
    case f11 = 0x67
    case f12 = 0x6F
    case f13 = 0x69
    case f14 = 0x6B
    case f15 = 0x71
    case f16 = 0x6A
    case f17 = 0x40
    case f18 = 0x4F
    case f19 = 0x50
    case f20 = 0x5A

    // US-ANSI Keyboard Positions
    // eg. These key codes are for the physical key (in any keyboard layout)
    // at the location of the named key in the US-ANSI layout.
    case a = 0x00
    case b = 0x0B
    case c = 0x08
    case d = 0x02
    case e = 0x0E
    case f = 0x03
    case g = 0x05
    case h = 0x04
    case i = 0x22
    case j = 0x26
    case k = 0x28
    case l = 0x25
    case m = 0x2E
    case n = 0x2D
    case o = 0x1F
    case p = 0x23
    case q = 0x0C
    case r = 0x0F
    case s = 0x01
    case t = 0x11
    case u = 0x20
    case v = 0x09
    case w = 0x0D
    case x = 0x07
    case y = 0x10
    case z = 0x06

    case zero = 0x1D
    case one = 0x12
    case two = 0x13
    case three = 0x14
    case four = 0x15
    case five = 0x17
    case six = 0x16
    case seven = 0x1A
    case eight = 0x1C
    case nine = 0x19

    case equals = 0x18
    case minus = 0x1B
    case semicolon = 0x29
    case apostrophe = 0x27
    case comma = 0x2B
    case period = 0x2F
    case forwardSlash = 0x2C
    case backslash = 0x2A
    case grave = 0x32
    case leftBracket = 0x21
    case rightBracket = 0x1E

    case keypadDecimal = 0x41
    case keypadMultiply = 0x43
    case keypadPlus = 0x45
    case keypadClear = 0x47
    case keypadDivide = 0x4B
    case keypadEnter = 0x4C
    case keypadMinus = 0x4E
    case keypadEquals = 0x51
    case keypad0 = 0x52
    case keypad1 = 0x53
    case keypad2 = 0x54
    case keypad3 = 0x55
    case keypad4 = 0x56
    case keypad5 = 0x57
    case keypad6 = 0x58
    case keypad7 = 0x59
    case keypad8 = 0x5B
    case keypad9 = 0x5C
}
func press(_ key: KeyCode, withModifiers modifiers: CGEventFlags = .init()) {
    let down = CGEvent(keyboardEventSource: src, virtualKey: key.rawValue, keyDown: true)!
    let up = CGEvent(keyboardEventSource: src, virtualKey: key.rawValue, keyDown: false)!
    down.flags = modifiers
    up.flags = modifiers
    down.post(tap: .cghidEventTap)
    up.post(tap: .cghidEventTap)
}
struct KeyPress {
    let key: KeyCode
    let modifiers: CGEventFlags
}
func press(_ key: KeyPress) {
    press(key.key, withModifiers: key.modifiers)
}
/// An enum representing possible typing rates.
///
/// - allAtOnce: All the text should be typed at once.
/// - consistent: The text should be typed at a reasonable speed, but with no variance in delay.
/// - natural: The text should be typed so that it appears natural.
/// - customConsistent: The text should be typed at a consistent speed, specified by the associated value.
/// - customVarying: The text should be typed around a given speed, with 5 possible ranges of variation. Both the base speed and the maximum variance are specified by associated values.
public enum Rate {
    /// All the text should be typed at once.
    case allAtOnce
    /// The text should be typed at a reasonable speed, but with no variance in delay.
    case consistent
    /// The text should be typed so that it appears natural.
    case natural
    /// The text should be typed at a specified consistent speed.
    /// - μsecondDelay: The delay between each key typed.
    case customConsistent(μsecondDelay: UInt32)
    /// The text should be typed around a specified given speed, with specified variation. The base delay should be the average delay time, and the max variance is the maximum distance from the average to the fastest/slowest possible delay.
    /// - μsecondBaseDelay: The base delay between each key typed.
    /// - maxVariance: The delay between each key typed.
    case customVarying(μsecondBaseDelay: UInt32, maxVariance: UInt32)
}

func type(_ text: [KeyPress], typing: Rate = .natural) {
    for character in text {
        press(character)
        switch typing {
        case .allAtOnce:
            usleep(0001000)
        case .consistent:
            usleep(0100000)
        case .natural:
            var sleepTime = UInt32.random(in: 0...4)
            sleepTime *= 10000
            usleep(0080000   sleepTime)
        case .customConsistent(let μsecondDelay):
            usleep(μsecondDelay)
        case let .customVarying(μsecondBaseDelay, maxVariance):
            var sleepTime = UInt32.random(in: 0...4)
            let base = μsecondBaseDelay - maxVariance
            sleepTime *= (maxVariance / 2)
            let μsecondDelay = base   sleepTime
            usleep(μsecondDelay)
        }
    }
}
let lowercaseCharMap: [Character: KeyCode] = [
    "a": .a,
    "b": .b,
    "c": .c,
    "d": .d,
    "e": .e,
    "f": .f,
    "g": .g,
    "h": .h,
    "i": .i,
    "j": .j,
    "k": .k,
    "l": .l,
    "m": .m,
    "n": .n,
    "o": .o,
    "p": .p,
    "q": .q,
    "r": .r,
    "s": .s,
    "t": .t,
    "u": .u,
    "v": .v,
    "w": .w,
    "x": .x,
    "y": .y,
    "z": .z,
    "0": .zero,
    "1": .one,
    "2": .two,
    "3": .three,
    "4": .four,
    "5": .five,
    "6": .six,
    "7": .seven,
    "8": .eight,
    "9": .nine,
    "=": .equals,
    "-": .minus,
    ";": .semicolon,
    "'": .apostrophe,
    ",": .comma,
    ".": .period,
    "/": .forwardSlash,
    "\\": .backslash,
    "`": .grave,
    "[": .leftBracket,
    "]": .rightBracket,
    " ": .space
]
let uppercaseCharMap: [Character: KeyCode] = [
    "A": .a,
    "B": .b,
    "C": .c,
    "D": .d,
    "E": .e,
    "F": .f,
    "G": .g,
    "H": .h,
    "I": .i,
    "J": .j,
    "K": .k,
    "L": .l,
    "M": .m,
    "N": .n,
    "O": .o,
    "P": .p,
    "Q": .q,
    "R": .r,
    "S": .s,
    "T": .t,
    "U": .u,
    "V": .v,
    "W": .w,
    "X": .x,
    "Y": .y,
    "Z": .z,
    ")": .zero,
    "!": .one,
    "@": .two,
    "#": .three,
    "$": .four,
    "%": .five,
    "^": .six,
    "&": .seven,
    "*": .eight,
    "(": .nine,
    " ": .equals,
    "_": .minus,
    ":": .semicolon,
    "\"": .apostrophe,
    "<": .comma,
    ">": .period,
    "?": .forwardSlash,
    "|": .backslash,
    "~": .grave,
    "{": .leftBracket,
    "}": .rightBracket,
]

func type(_ text: String, typing: Rate = .natural) {
    type(str_to_kparr(text), typing: typing)
}

type("Hello, there")

func str_to_kparr(_ str: String) -> [KeyPress] {
    str.map { char -> KeyPress in
        if let kc = lowercaseCharMap[char] {
            return KeyPress(key: kc, modifiers: .init())
        }
        if let kc = uppercaseCharMap[char] {
            return KeyPress(key: kc, modifiers: .maskShift)
        }
        return KeyPress(key: .three, modifiers: .maskShift)
    }
}

func  (lhs: String, rhs: [KeyPress]) -> [KeyPress] {
    return str_to_kparr(lhs)   rhs
}
func  (lhs: [KeyPress], rhs: String) -> [KeyPress] {
    return lhs   str_to_kparr(rhs)
}

type("! General Kenobi"   [.init(key: .a, modifiers: .maskCommand), .init(key: .delete, modifiers: .init()), .init(key: .space, modifiers: [.maskCommand])])

extension KeyPress {
    static let returnKey = KeyPress(key: .returnKey, modifiers: .init())
    static let enter = Self.returnKey
    static let tab = KeyPress(key: .tab, modifiers: .init())
    static let space = KeyPress(key: .space, modifiers: .init())
    static let delete = KeyPress(key: .delete, modifiers: .init())
    static let escape = KeyPress(key: .escape, modifiers: .init())
    static let command = KeyPress(key: .command, modifiers: .init())
    static let shift = KeyPress(key: .shift, modifiers: .init())
    static let capsLock = KeyPress(key: .capsLock, modifiers: .init())
    static let option = KeyPress(key: .option, modifiers: .init())
    static let control = KeyPress(key: .control, modifiers: .init())
    static let rightShift = KeyPress(key: .rightShift, modifiers: .init())
    static let rightOption = KeyPress(key: .rightOption, modifiers: .init())
    static let rightControl = KeyPress(key: .rightControl, modifiers: .init())
    static let leftArrow = KeyPress(key: .leftArrow, modifiers: .init())
    static let rightArrow = KeyPress(key: .rightArrow, modifiers: .init())
    static let downArrow = KeyPress(key: .downArrow, modifiers: .init())
    static let upArrow = KeyPress(key: .upArrow, modifiers: .init())
    static let volumeUp = KeyPress(key: .volumeUp, modifiers: .init())
    static let volumeDown = KeyPress(key: .volumeDown, modifiers: .init())
    static let mute = KeyPress(key: .mute, modifiers: .init())
    static let help = KeyPress(key: .help, modifiers: .init())
    static let home = KeyPress(key: .home, modifiers: .init())
    static let pageUp = KeyPress(key: .pageUp, modifiers: .init())
    static let forwardDelete = KeyPress(key: .forwardDelete, modifiers: .init())
    static let end = KeyPress(key: .end, modifiers: .init())
    static let pageDown = KeyPress(key: .pageDown, modifiers: .init())
    static let function = KeyPress(key: .function, modifiers: .init())
    static let f1 = KeyPress(key: .f1, modifiers: .init())
    static let f2 = KeyPress(key: .f2, modifiers: .init())
    static let f4 = KeyPress(key: .f4, modifiers: .init())
    static let f5 = KeyPress(key: .f5, modifiers: .init())
    static let f6 = KeyPress(key: .f6, modifiers: .init())
    static let f7 = KeyPress(key: .f7, modifiers: .init())
    static let f3 = KeyPress(key: .f3, modifiers: .init())
    static let f8 = KeyPress(key: .f8, modifiers: .init())
    static let f9 = KeyPress(key: .f9, modifiers: .init())
    static let f10 = KeyPress(key: .f10, modifiers: .init())
    static let f11 = KeyPress(key: .f11, modifiers: .init())
    static let f12 = KeyPress(key: .f12, modifiers: .init())
    static let f13 = KeyPress(key: .f13, modifiers: .init())
    static let f14 = KeyPress(key: .f14, modifiers: .init())
    static let f15 = KeyPress(key: .f15, modifiers: .init())
    static let f16 = KeyPress(key: .f16, modifiers: .init())
    static let f17 = KeyPress(key: .f17, modifiers: .init())
    static let f18 = KeyPress(key: .f18, modifiers: .init())
    static let f19 = KeyPress(key: .f19, modifiers: .init())
    static let f20 = KeyPress(key: .f20, modifiers: .init())

        // US-ANSI Keyboard Positions
        // eg. These key codes are for the physical key (in any keyboard layout)
        // at the location of the named key in the US-ANSI layout.
    static let a = KeyPress(key: .a, modifiers: .init())
    static let b = KeyPress(key: .b, modifiers: .init())
    static let c = KeyPress(key: .c, modifiers: .init())
    static let d = KeyPress(key: .d, modifiers: .init())
    static let e = KeyPress(key: .e, modifiers: .init())
    static let f = KeyPress(key: .f, modifiers: .init())
    static let g = KeyPress(key: .g, modifiers: .init())
    static let h = KeyPress(key: .h, modifiers: .init())
    static let i = KeyPress(key: .i, modifiers: .init())
    static let j = KeyPress(key: .j, modifiers: .init())
    static let k = KeyPress(key: .k, modifiers: .init())
    static let l = KeyPress(key: .l, modifiers: .init())
    static let m = KeyPress(key: .m, modifiers: .init())
    static let n = KeyPress(key: .n, modifiers: .init())
    static let o = KeyPress(key: .o, modifiers: .init())
    static let p = KeyPress(key: .p, modifiers: .init())
    static let q = KeyPress(key: .q, modifiers: .init())
    static let r = KeyPress(key: .r, modifiers: .init())
    static let s = KeyPress(key: .s, modifiers: .init())
    static let t = KeyPress(key: .t, modifiers: .init())
    static let u = KeyPress(key: .u, modifiers: .init())
    static let v = KeyPress(key: .v, modifiers: .init())
    static let w = KeyPress(key: .w, modifiers: .init())
    static let x = KeyPress(key: .x, modifiers: .init())
    static let y = KeyPress(key: .y, modifiers: .init())
    static let z = KeyPress(key: .z, modifiers: .init())
    static let A = KeyPress(key: .a, modifiers: .maskShift)
    static let B = KeyPress(key: .b, modifiers: .maskShift)
    static let C = KeyPress(key: .c, modifiers: .maskShift)
    static let D = KeyPress(key: .d, modifiers: .maskShift)
    static let E = KeyPress(key: .e, modifiers: .maskShift)
    static let F = KeyPress(key: .f, modifiers: .maskShift)
    static let G = KeyPress(key: .g, modifiers: .maskShift)
    static let H = KeyPress(key: .h, modifiers: .maskShift)
    static let I = KeyPress(key: .i, modifiers: .maskShift)
    static let J = KeyPress(key: .j, modifiers: .maskShift)
    static let K = KeyPress(key: .k, modifiers: .maskShift)
    static let L = KeyPress(key: .l, modifiers: .maskShift)
    static let M = KeyPress(key: .m, modifiers: .maskShift)
    static let N = KeyPress(key: .n, modifiers: .maskShift)
    static let O = KeyPress(key: .o, modifiers: .maskShift)
    static let P = KeyPress(key: .p, modifiers: .maskShift)
    static let Q = KeyPress(key: .q, modifiers: .maskShift)
    static let R = KeyPress(key: .r, modifiers: .maskShift)
    static let S = KeyPress(key: .s, modifiers: .maskShift)
    static let T = KeyPress(key: .t, modifiers: .maskShift)
    static let U = KeyPress(key: .u, modifiers: .maskShift)
    static let V = KeyPress(key: .v, modifiers: .maskShift)
    static let W = KeyPress(key: .w, modifiers: .maskShift)
    static let X = KeyPress(key: .x, modifiers: .maskShift)
    static let Y = KeyPress(key: .y, modifiers: .maskShift)
    static let Z = KeyPress(key: .z, modifiers: .maskShift)

    static let zero = KeyPress(key: .zero, modifiers: .init())
    static let one = KeyPress(key: .one, modifiers: .init())
    static let two = KeyPress(key: .two, modifiers: .init())
    static let three = KeyPress(key: .three, modifiers: .init())
    static let four = KeyPress(key: .four, modifiers: .init())
    static let five = KeyPress(key: .five, modifiers: .init())
    static let six = KeyPress(key: .six, modifiers: .init())
    static let seven = KeyPress(key: .seven, modifiers: .init())
    static let eight = KeyPress(key: .eight, modifiers: .init())
    static let nine = KeyPress(key: .nine, modifiers: .init())
    static let leftParenthesis = KeyPress(key: .zero, modifiers: .maskShift)
    static let exclamationPoint = KeyPress(key: .one, modifiers: .maskShift)
    static let atSign = KeyPress(key: .two, modifiers: .maskShift)
    static let numberSign = KeyPress(key: .three, modifiers: .maskShift)
    static let dollarSign = KeyPress(key: .four, modifiers: .maskShift)
    static let percent = KeyPress(key: .five, modifiers: .maskShift)
    static let caret = KeyPress(key: .six, modifiers: .maskShift)
    static let ampersand = KeyPress(key: .seven, modifiers: .maskShift)
    static let asterisk = KeyPress(key: .eight, modifiers: .maskShift)
    static let rightParenthesis = KeyPress(key: .nine, modifiers: .maskShift)

    static let equals = KeyPress(key: .equals, modifiers: .init())
    static let minus = KeyPress(key: .minus, modifiers: .init())
    static let semicolon = KeyPress(key: .semicolon, modifiers: .init())
    static let apostrophe = KeyPress(key: .apostrophe, modifiers: .init())
    static let comma = KeyPress(key: .comma, modifiers: .init())
    static let period = KeyPress(key: .period, modifiers: .init())
    static let forwardSlash = KeyPress(key: .forwardSlash, modifiers: .init())
    static let backslash = KeyPress(key: .backslash, modifiers: .init())
    static let grave = KeyPress(key: .grave, modifiers: .init())
    static let leftBracket = KeyPress(key: .leftBracket, modifiers: .init())
    static let rightBracket = KeyPress(key: .rightBracket, modifiers: .init())
    static let plus = KeyPress(key: .equals, modifiers: .maskShift)
    static let underscore = KeyPress(key: .minus, modifiers: .maskShift)
    static let colon = KeyPress(key: .semicolon, modifiers: .maskShift)
    static let quotationMark = KeyPress(key: .apostrophe, modifiers: .maskShift)
    static let lessThan = KeyPress(key: .comma, modifiers: .maskShift)
    static let greaterThan = KeyPress(key: .period, modifiers: .maskShift)
    static let questionMark = KeyPress(key: .forwardSlash, modifiers: .maskShift)
    static let pipe = KeyPress(key: .backslash, modifiers: .maskShift)
    static let tilde = KeyPress(key: .grave, modifiers: .maskShift)
    static let leftBrace = KeyPress(key: .leftBracket, modifiers: .maskShift)
    static let rightBrace = KeyPress(key: .rightBracket, modifiers: .maskShift)

    static let keypadDecimal = KeyPress(key: .keypadDecimal, modifiers: .init())
    static let keypadMultiply = KeyPress(key: .keypadMultiply, modifiers: .init())
    static let keypadPlus = KeyPress(key: .keypadPlus, modifiers: .init())
    static let keypadClear = KeyPress(key: .keypadClear, modifiers: .init())
    static let keypadDivide = KeyPress(key: .keypadDivide, modifiers: .init())
    static let keypadEnter = KeyPress(key: .keypadEnter, modifiers: .init())
    static let keypadMinus = KeyPress(key: .keypadMinus, modifiers: .init())
    static let keypadEquals = KeyPress(key: .keypadEquals, modifiers: .init())
    static let keypad0 = KeyPress(key: .keypad0, modifiers: .init())
    static let keypad1 = KeyPress(key: .keypad1, modifiers: .init())
    static let keypad2 = KeyPress(key: .keypad2, modifiers: .init())
    static let keypad3 = KeyPress(key: .keypad3, modifiers: .init())
    static let keypad4 = KeyPress(key: .keypad4, modifiers: .init())
    static let keypad5 = KeyPress(key: .keypad5, modifiers: .init())
    static let keypad6 = KeyPress(key: .keypad6, modifiers: .init())
    static let keypad7 = KeyPress(key: .keypad7, modifiers: .init())
    static let keypad8 = KeyPress(key: .keypad8, modifiers: .init())
    static let keypad9 = KeyPress(key: .keypad9, modifiers: .init())
}

extension KeyPress {
    func withModifiers(_ modifiers: CGEventFlags) -> KeyPress {
        return KeyPress(key: self.key, modifiers: modifiers)
    }
    func appendingModifiers(_ modifiers: CGEventFlags) -> KeyPress {
        return self.withModifiers(self.modifiers.union(modifiers))
    }
}

sleep(2)
type([KeyPress.space.withModifiers([.maskCommand])]   "My name is Inigo Montoya. You killed my father. Prepare to die"   [KeyPress.space.withModifiers([.maskCommand]), KeyPress.tab.withModifiers(.maskCommand), .command])

func  (lhs: String, rhs: KeyPress) -> [KeyPress] {
    return lhs   [rhs]
}
func  (lhs: KeyPress, rhs: String) -> [KeyPress] {
    return [lhs]   rhs
}

type([KeyPress.tab.withModifiers(.maskCommand), .command, KeyPress.space.withModifiers([.maskCommand])]   "?")

一些注意事項:

  • 我不知道是否CGEventSource(stateID: .hidSystemState)正確,或者是否應該是不同的狀態。檢查檔案
  • down.post(tap: .cghidEventTap)(檔案)相同
  • 請注意,您需要發布一個keyDown: true事件一個keydown: false事件。
  • 顯然,你不能鍵入特殊字符,如?,所以這個代碼列印#,而不是
  • 否則,您可以將字串傳遞給type(_:typing:)它,它會輸入它。
  • 在運行之前仔細閱讀這段代碼——它被設計為在 Spotlight 系結到命令空間的情況下運行(否則它可能會#重要的地方輸入),并將在第二個打開的應用程式的末尾輸入 a
  • 打字率列舉來自我的Typer 庫,它使用 AppleScript 打字(您的另一種選擇),但不支持修飾符。

如果您只使用 Mac,也可以使用 AppleScript 進行輸入。我相信這會做到:

tell app "System Events" to keystroke "v" using command down
tell app "System Events" to keystroke "v" using {shift down, command down}

看看我的 Typer 庫,看看我是如何編譯和運行 AppleScript 的。

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/342722.html

標籤:迅速 苹果系统 迅捷 键盘快捷键

上一篇:有沒有人能夠限制在SwiftUI3中放置在mac上的物件的型別?

下一篇:如何在Mac作業系統上安裝pyrealsense2?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more